diff options
Diffstat (limited to 'thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL')
9 files changed, 4978 insertions, 0 deletions
diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/Release_Notes.html b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/Release_Notes.html new file mode 100644 index 0000000..c189a18 --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/Release_Notes.html @@ -0,0 +1,153 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40"><head> + + + + + + + + + + <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> + + + <link rel="File-List" href="Library_files/filelist.xml"> + + + <link rel="Edit-Time-Data" href="Library_files/editdata.mso"><!--[if !mso]> <style> v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><title>Release Notes for STM32303C_EVAL Evaluation Board Drivers</title><!--[if gte mso 9]><xml> <o:DocumentProperties> <o:Author>STMicroelectronics</o:Author> <o:LastAuthor>STMicroelectronics</o:LastAuthor> <o:Revision>37</o:Revision> <o:TotalTime>136</o:TotalTime> <o:Created>2009-02-27T19:26:00Z</o:Created> <o:LastSaved>2009-03-01T17:56:00Z</o:LastSaved> <o:Pages>1</o:Pages> <o:Words>522</o:Words> <o:Characters>2977</o:Characters> <o:Company>STMicroelectronics</o:Company> <o:Lines>24</o:Lines> <o:Paragraphs>6</o:Paragraphs> <o:CharactersWithSpaces>3493</o:CharactersWithSpaces> <o:Version>11.6568</o:Version> </o:DocumentProperties> </xml><![endif]--><!--[if gte mso 9]><xml> <w:WordDocument> <w:Zoom>110</w:Zoom> <w:ValidateAgainstSchemas/> <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid> <w:IgnoreMixedContent>false</w:IgnoreMixedContent> <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText> <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel> </w:WordDocument> </xml><![endif]--><!--[if gte mso 9]><xml> <w:LatentStyles DefLockedState="false" LatentStyleCount="156"> </w:LatentStyles> </xml><![endif]--> + + + + + + + + <style> +<!-- +/* Style Definitions */ +p.MsoNormal, li.MsoNormal, div.MsoNormal +{mso-style-parent:""; +margin:0in; +margin-bottom:.0001pt; +mso-pagination:widow-orphan; +font-size:12.0pt; +font-family:"Times New Roman"; +mso-fareast-font-family:"Times New Roman";} +h2 +{mso-style-next:Normal; +margin-top:12.0pt; +margin-right:0in; +margin-bottom:3.0pt; +margin-left:0in; +mso-pagination:widow-orphan; +page-break-after:avoid; +mso-outline-level:2; +font-size:14.0pt; +font-family:Arial; +font-weight:bold; +font-style:italic;} +a:link, span.MsoHyperlink +{color:blue; +text-decoration:underline; +text-underline:single;} +a:visited, span.MsoHyperlinkFollowed +{color:blue; +text-decoration:underline; +text-underline:single;} +p +{mso-margin-top-alt:auto; +margin-right:0in; +mso-margin-bottom-alt:auto; +margin-left:0in; +mso-pagination:widow-orphan; +font-size:12.0pt; +font-family:"Times New Roman"; +mso-fareast-font-family:"Times New Roman";} +@page Section1 +{size:8.5in 11.0in; +margin:1.0in 1.25in 1.0in 1.25in; +mso-header-margin:.5in; +mso-footer-margin:.5in; +mso-paper-source:0;} +div.Section1 +{page:Section1;} +--> + </style><!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable {mso-style-name:"Table Normal"; mso-tstyle-rowband-size:0; mso-tstyle-colband-size:0; mso-style-noshow:yes; mso-style-parent:""; mso-padding-alt:0in 5.4pt 0in 5.4pt; mso-para-margin:0in; mso-para-margin-bottom:.0001pt; mso-pagination:widow-orphan; font-size:10.0pt; font-family:"Times New Roman"; mso-ansi-language:#0400; mso-fareast-language:#0400; mso-bidi-language:#0400;} </style> <![endif]--><!--[if gte mso 9]><xml> <o:shapedefaults v:ext="edit" spidmax="5122"/> </xml><![endif]--><!--[if gte mso 9]><xml> <o:shapelayout v:ext="edit"> <o:idmap v:ext="edit" data="1"/> </o:shapelayout></xml><![endif]--> + <meta content="MCD Application Team" name="author"></head> +<body link="blue" vlink="blue"> +<div class="Section1"> +<p class="MsoNormal"><span style="font-family: Arial;"><o:p><br> +</o:p></span></p> +<div align="center"> +<table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900"> + <tbody> + <tr> + <td style="padding: 0cm;" valign="top"> + <table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" cellspacing="0" width="900"> + <tbody> + <tr> + <td style="vertical-align: top;"> + <p class="MsoNormal"><span style="font-size: 8pt; font-family: Arial; color: blue;"><a href="../../../Release_Notes.html">Back to Release page</a><o:p></o:p></span></p> + </td> + </tr> + <tr style=""> + <td style="padding: 1.5pt;"> + <h1 style="margin-bottom: 18pt; text-align: center;" align="center"><span style="font-size: 20pt; font-family: Verdana; color: rgb(51, 102, 255);">Release +Notes for STM32303C_EVAL Evaluation Board Drivers</span><span style="font-size: 20pt; font-family: Verdana;"><o:p></o:p></span></h1> + <p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: Arial; color: black;">Copyright +2012 STMicroelectronics</span><span style="color: black;"><u1:p></u1:p><o:p></o:p></span></p> + <p class="MsoNormal" style="text-align: center;" align="center"><span style="font-size: 10pt; font-family: Arial; color: black;"><img alt="" id="_x0000_i1025" src="../../../_htmresc/logo.bmp" style="border: 0px solid ; width: 86px; height: 65px;"></span><span style="font-size: 10pt;"><o:p></o:p></span></p> + </td> + </tr> + </tbody> + </table> + <p class="MsoNormal"><span style="font-family: Arial; display: none;"><o:p> </o:p></span></p> + <table class="MsoNormalTable" style="width: 675pt;" border="0" cellpadding="0" width="900"> + <tbody> + <tr style=""> + <td style="padding: 0cm;" valign="top"> + <h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><span style="font-size: 12pt; color: white;">Contents<o:p></o:p></span></h2> + <ol style="margin-top: 0cm;" start="1" type="1"> + <li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;"><a href="#History">STM32303C_EVAL Evaluation Board Drivers +update History</a><o:p></o:p></span></li> + <li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;"><a href="#License">License</a><o:p></o:p></span></li> + </ol> + <span style="font-family: "Times New Roman";"> + </span> + <h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><a name="History"></a><span style="font-size: 12pt; color: white;">STM32303C_EVAL Evaluation Board Drivers update History</span></h2><h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 167px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.1 /23-October-2012<o:p></o:p></span></h3><p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Main +Changes<o:p></o:p></span></u></b></p> +<ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;"></span><span style="font-size: 10pt; font-family: Verdana;">stm32303c_eval_lcd.c/h</span></li><ul><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;">Add the support of new LCD controller HX-8347D <span style="font-weight: bold;"><br><span style="text-decoration: underline;"></span></span></span></li></ul></ul><h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 167px;"><span style="font-size: 10pt; font-family: Arial; color: white;">V1.0.0 /02-October-2012</span></h3><h3 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial; margin-right: 500pt; width: 167px;"><span style="font-size: 10pt; font-family: Arial; color: white;"><o:p></o:p></span></h3><p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt;"><b style=""><u><span style="font-size: 10pt; font-family: Verdana; color: black;">Main +Changes<o:p></o:p></span></u></b></p> +<ul style="margin-top: 0cm;" type="square"><li class="MsoNormal" style="color: black; margin-top: 4.5pt; margin-bottom: 4.5pt;"><span style="font-size: 10pt; font-family: Verdana;"></span><span style="font-size: 10pt; font-family: Verdana;">First official release for +<span style="font-style: italic; font-weight: bold;">STM32F30x devices</span></span></li></ul><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"><span style="font-style: italic; font-weight: bold;"></span></span><span style="font-size: 10pt; font-family: Verdana;"></span><h2 style="background: rgb(51, 102, 255) none repeat scroll 0% 50%; -moz-background-clip: initial; -moz-background-origin: initial; -moz-background-inline-policy: initial;"><a name="License"></a><span style="font-size: 12pt; color: white;">License<o:p></o:p></span></h2><p class="MsoNormal"><span style="font-size: 10pt; color: black; font-family: 'Verdana','sans-serif';">Licensed +under MCD-ST Liberty SW License Agreement V2, (the "License"); You may not use +this </span><span style="font-size: 10pt; color: black; font-family: 'Verdana','sans-serif';">package</span><span style="font-size: 10pt; color: black; font-family: 'Verdana','sans-serif';"> +except in compliance with the License. You may obtain a copy of the License +at:<br><br></span></p> +<div style="text-align: center;"><span style="font-size: 10pt; color: black; font-family: 'Verdana','sans-serif';"> +<a href="http://www.st.com/software_license_agreement_liberty_v2" target="_blank">http://www.st.com/software_license_agreement_liberty_v2</a></span><br><span style="font-size: 10pt; color: black; font-family: 'Verdana','sans-serif';"></span></div><span style="font-size: 10pt; color: black; font-family: 'Verdana','sans-serif';"><br>Unless +required by applicable law or agreed to in writing, software distributed under +the License is distributed on an "AS IS" BASIS, <br>WITHOUT WARRANTIES OR +CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the +License.</span><b><span style="font-size: 10pt; font-family: Verdana; color: black;"></span></b> + + <div class="MsoNormal" style="text-align: center;" align="center"><span style="color: black;"> + <hr align="center" size="2" width="100%"></span></div> + <p class="MsoNormal" style="margin: 4.5pt 0cm 4.5pt 18pt; text-align: center;" align="center"><span style="font-size: 10pt; color: black; font-family: 'Verdana','sans-serif';">For +complete documentation on </span><span style="font-size: 10pt; font-family: 'Verdana','sans-serif';">STM32<span style="color: black;"> Microcontrollers visit </span></span><span style="font-size: 10pt; font-family: "Verdana","sans-serif";"><u><span style="color: blue;"></span></u></span><u><a href="http://www.st.com/stm32f3" target="_blank">www.st.com/stm32f3</a></u><span style="font-size: 10pt; font-family: Verdana;"><a href="http://www.st.com/internet/mcu/family/141.jsp" target="_blank"><u><span style="color: blue;"></span></u></a></span><span style="color: black;"><o:p></o:p></span></p> + </td> + </tr> + </tbody> + </table> + <p class="MsoNormal"><span style="font-size: 10pt;"><o:p></o:p></span></p> + </td> + </tr> + </tbody> +</table> +</div> +<p class="MsoNormal"><o:p> </o:p></p> +</div> + +</body></html>
\ No newline at end of file diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee_cpal.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee_cpal.c new file mode 100644 index 0000000..3e247a0 --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee_cpal.c @@ -0,0 +1,580 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_i2c_ee_cpal.c + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file provides a set of functions needed to manage I2C + * EEPROM memory. + * + * =================================================================== + * Notes: + * - This driver is intended for STM32F30x families devices only. + * - The I2C EEPROM memory (M24LR64) is available in RF EEPROM daughter + * board (ANT7-M24LR-A) provided with the EVAL board, to use this + * driver you have to connect the ANT7-M24LR-A to CN1 connector. + * =================================================================== + * + * It implements a high level communication layer for read and write + * from/to this memory. + * + * @note This file has been updated to use the CPAL library drivers + * instead of the Standard peripheral drivers. + * + * @note In this driver, basic read and write functions (sEE_ReadBuffer() + * and sEE_WritePage()) use the DMA or Interrupt to perform the + * data transfer to/from EEPROM memory. + * Thus, after calling these two functions, user application may + * perform other tasks while data transfer is ongoing. + * The application should then monitor the variable holding + * the state of EEPROM in order to determine when the transfer is + * completed . Stopping transfer tasks are performed into DMA or I2C + * interrupt handlers (which are integrated into this driver). + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval_i2c_ee_cpal.h" + + +/* Private typedef -----------------------------------------------------------*/ + +/*========= sEE_Write_TypeDef =========*/ +/* sEE Write parameter structure definition */ + +typedef struct +{ + __IO uint32_t sEEDataNum; /*!< The number of data that will be written in next transfer */ + + uint32_t sEEWriteAddr; /*!< Physical memory address of EEPROM where data will be written */ + + __IO uint8_t *sEEpBuffer; /*!< The address of the buffer from which data transfer should start */ + + __IO uint16_t sEENumOfPage; /*!< The number of page that will be written */ + + __IO uint8_t sEENumOfSingle; /*!< The number of single data that will be written */ + + __IO uint8_t sEENextWrite; /*!< This member indicates there is remaining transfers */ + +} sEE_WriteTypeDef; + +/* Private defines -----------------------------------------------------------*/ +/* Private macro -------------------------------------------------------------*/ +/* Private variables ---------------------------------------------------------*/ + +/*========= Local Structures declaration =========*/ + +#ifdef CPAL_USE_I2C1 + sEE_InitTypeDef sEE1_DevStructure = {&I2C1_DevStructure, 0, 0, 0, sEE_STATE_IDLE}; /* Initialize All structure parameters to 0 */ +#endif /* CPAL_USE_I2C1 */ + +#ifdef CPAL_USE_I2C2 + sEE_InitTypeDef sEE2_DevStructure = {&I2C2_DevStructure, 0, 0, 0, sEE_STATE_IDLE}; /* Initialize All structure parameters to 0 */ +#endif /* CPAL_USE_I2C2 */ + +sEE_InitTypeDef* sEE_DevStructures[CPAL_I2C_DEV_NUM] = +{ +#ifdef CPAL_USE_I2C1 + &sEE1_DevStructure, +#else + pNULL, +#endif + +#ifdef CPAL_USE_I2C2 + &sEE2_DevStructure, +#else + pNULL, +#endif +}; + +#ifdef CPAL_USE_I2C1 + sEE_WriteTypeDef sEE1_WriteStructure = {0, 0, pNULL, 0, 0, 0}; /* Initialize All structure parameters to 0 */ +#endif /* CPAL_USE_I2C1 */ + +#ifdef CPAL_USE_I2C2 + sEE_WriteTypeDef sEE2_WriteStructure = {0, 0, pNULL, 0, 0, 0}; /* Initialize All structure parameters to 0 */ +#endif /* CPAL_USE_I2C2 */ + +sEE_WriteTypeDef* sEE_WriteStructures[CPAL_I2C_DEV_NUM] = +{ +#ifdef CPAL_USE_I2C1 + &sEE1_WriteStructure, +#else + pNULL, +#endif + +#ifdef CPAL_USE_I2C2 + &sEE2_WriteStructure, +#else + pNULL, +#endif +}; + +#ifdef CPAL_USE_I2C1 +CPAL_TransferTypeDef sEE1_TXTransfer = { + /* Initialize TX Transfer structure */ + pNULL, + 0, + 0, + 0}; + +CPAL_TransferTypeDef sEE1_RXTransfer = { + /* Initialize RX Transfer structure */ + pNULL, + 0, + 0, + 0}; +#endif /* CPAL_USE_I2C1 */ + +#ifdef CPAL_USE_I2C2 +CPAL_TransferTypeDef sEE2_TXTransfer = { + /* Initialize TX Transfer structure */ + pNULL, + 0, + 0, + 0}; + +CPAL_TransferTypeDef sEE2_RXTransfer = { + /* Initialize RX Transfer structure */ + pNULL, + 0, + 0, + 0}; +#endif /* CPAL_USE_I2C2 */ + +CPAL_TransferTypeDef* sEE_TXTransfer[CPAL_I2C_DEV_NUM] = +{ +#ifdef CPAL_USE_I2C1 + &sEE1_TXTransfer, +#else + pNULL, +#endif + +#ifdef CPAL_USE_I2C2 + &sEE2_TXTransfer, +#else + pNULL, +#endif +}; + + +CPAL_TransferTypeDef* sEE_RXTransfer[CPAL_I2C_DEV_NUM] = +{ +#ifdef CPAL_USE_I2C1 + &sEE1_RXTransfer, +#else + pNULL, +#endif + +#ifdef CPAL_USE_I2C2 + &sEE2_RXTransfer, +#else + pNULL, +#endif +}; + +/** + * @} + */ + +/* Private function prototypes -----------------------------------------------*/ + + +static uint32_t sEE_WritePage(sEE_InitTypeDef* sEEInitStruct, uint8_t* pBuffer, \ + uint16_t WriteAddr, uint32_t NumByteToWrite); + +/* Private functions ---------------------------------------------------------*/ + +/** + * @brief DeInitialize peripherals used by the I2C EEPROM driver. + * @param sEEInitStruct : Pointer to sEE Device structure + * @retval None + */ +void sEE_DeInit(sEE_InitTypeDef* sEEInitStruct) +{ + /* Deinitialize CPAL peripheral */ + CPAL_I2C_DeInit(sEEInitStruct->sEE_CPALStructure); +} + +/** + * @brief Initialize peripherals used by the I2C EEPROM driver. + * @param sEEInitStruct : Pointer to sEE Device structure + * @retval None + */ +void sEE_Init(sEE_InitTypeDef* sEEInitStruct) +{ + /* Initialize CPAL peripheral */ + CPAL_I2C_Init(sEEInitStruct->sEE_CPALStructure); +} + +/** + * @brief Initialize sEE CPAL Structure used by the I2C EEPROM driver. + * @param sEEInitStruct : Pointer to sEE Device structure + * @retval None + */ +void sEE_StructInit(sEE_InitTypeDef* sEEInitStruct) +{ + /* Set CPAL structure parameters to their default values */ + CPAL_I2C_StructInit(sEEInitStruct->sEE_CPALStructure); + + /* Set I2C clock speed */ + sEEInitStruct->sEE_CPALStructure->pCPAL_I2C_Struct->I2C_Timing = sEE_I2C_TIMING; + + sEEInitStruct->sEE_CPALStructure->wCPAL_Options = 0; + +#ifdef sEE_IT + /* Select Interrupt programming model and disable all options */ + sEEInitStruct->sEE_CPALStructure->CPAL_ProgModel = CPAL_PROGMODEL_INTERRUPT; +#else + /* Select DMA programming model and activate TX_DMA_TC and RX_DMA_TC interrupts */ + sEEInitStruct->sEE_CPALStructure->CPAL_ProgModel = CPAL_PROGMODEL_DMA; +#endif /* sEE_IT */ + +} + +/** + * @brief Reads a block of data from the EEPROM. + * @param sEEInitStruct : Pointer to sEE Device structure + * @param pBuffer : pointer to the buffer that receives the data read from + * the EEPROM. + * @param ReadAddr : EEPROM's internal address to read from. + * @param NumByteToRead : pointer to the variable holding number of bytes to + * read from the EEPROM. + * + * @note The variable pointed by NumByteToRead is reset to 0 when all the + * data are read from the EEPROM. Application should monitor this + * variable in order know when the transfer is complete. + * + * @note When number of data to be read is higher than 1, this function just + * configure the communication and enable the DMA channel to transfer data. + * Meanwhile, the user application may perform other tasks. + * When number of data to be read is 1, then the DMA is not used. + * + * @retval None + */ +uint32_t sEE_ReadBuffer(sEE_InitTypeDef* sEEInitStruct, uint8_t* pBuffer, \ + uint16_t ReadAddr, uint32_t NumByteToRead) +{ + if (sEEInitStruct->sEEState == sEE_STATE_IDLE) + { + sEEInitStruct->sEEState = sEE_STATE_READING; + + sEEInitStruct->sEE_CPALStructure->wCPAL_Options = 0; + + /* Enable 16Bit memory register option on CPAL */ + if (sEEInitStruct->sEEMemoryAddrMode & sEE_OPT_16BIT_REG) + { + sEEInitStruct->sEE_CPALStructure->wCPAL_Options = CPAL_OPT_16BIT_REG; + } + + /* Enable no memory addressing mode option on CPAL */ + if (sEEInitStruct->sEEMemoryAddrMode & sEE_OPT_NO_MEM_ADDR) + { + sEEInitStruct->sEE_CPALStructure->wCPAL_Options |= CPAL_OPT_NO_MEM_ADDR; + } + + sEEInitStruct->sEE_CPALStructure->pCPAL_TransferRx = sEE_RXTransfer[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]; + + sEEInitStruct->sEE_CPALStructure->pCPAL_TransferRx->wNumData = (uint32_t)(NumByteToRead); + sEEInitStruct->sEE_CPALStructure->pCPAL_TransferRx->pbBuffer = pBuffer; + sEEInitStruct->sEE_CPALStructure->pCPAL_TransferRx->wAddr1 = (uint32_t)((uint8_t)sEEInitStruct->sEEAddress); + sEEInitStruct->sEE_CPALStructure->pCPAL_TransferRx->wAddr2 = (uint32_t)((uint16_t)ReadAddr); + + return CPAL_I2C_Read(sEEInitStruct->sEE_CPALStructure); + } + else + { + return CPAL_FAIL; + } +} + +/** + * @brief Writes buffer of data to the I2C EEPROM. + * @param sEEInitStruct : Pointer to sEE Device structure + * @param pBuffer : pointer to the buffer containing the data to be written + * to the EEPROM. + * @param WriteAddr : EEPROM's internal address to write to. + * @param NumByteToWrite : number of bytes to write to the EEPROM. + * @retval None + */ +uint32_t sEE_WriteBuffer(sEE_InitTypeDef* sEEInitStruct, uint8_t* pBuffer, \ + uint16_t WriteAddr, uint32_t NumByteToWrite) +{ + uint32_t DataNum = 0; + uint16_t count = 0; + uint16_t Addr = 0; + + if (sEEInitStruct->sEEState == sEE_STATE_IDLE) + { + sEEInitStruct->sEEState = sEE_STATE_WRITING; + + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEEDataNum = 0; + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEEWriteAddr = 0; + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEEpBuffer = pNULL; + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENumOfPage = 0; + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENextWrite = 0; + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENumOfSingle = 0; + + /* if one data will be written */ + if (NumByteToWrite == 1) + { + /* Transfer complete */ + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENextWrite = 0; + + /* update number od data for write */ + DataNum = NumByteToWrite; + + if(sEE_WritePage(sEEInitStruct, pBuffer, WriteAddr, DataNum) != CPAL_PASS) + { + return CPAL_FAIL; + } + } + /* Use Write page */ + else + { + /* if Address aligned reset count value to 0 */ + Addr = WriteAddr % sEEInitStruct->sEEPageSize; + + if (Addr == 0) + { + count = 0; + } + else + { + count = sEEInitStruct->sEEPageSize - Addr; + + if (NumByteToWrite <= count) + { + count = NumByteToWrite; + } + } + + /* Get Number of page for write and number of single byte */ + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENumOfPage = \ + (uint16_t)((NumByteToWrite - count) / sEEInitStruct->sEEPageSize); + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENumOfSingle = \ + (uint8_t)((NumByteToWrite - count) % sEEInitStruct->sEEPageSize); + + /* If WriteAddr is sEE_PAGESIZE is not aligned */ + if (Addr != 0) + { + /* Update Number of data to write */ + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEEDataNum = count; + } + /* If WriteAddr is sEE_PAGESIZE is aligned */ + else + { + /* if only single byte must be written */ + if (sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENumOfPage == 0) + { + /* update number of data to write */ + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEEDataNum = \ + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENumOfSingle; + + /* reset number of single */ + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENumOfSingle = 0; + } + else + { + /* update number of data to write */ + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEEDataNum = (uint32_t)((uint16_t)sEEInitStruct->sEEPageSize); + + /* update number of page */ + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENumOfPage--; + } + } + + /* update global variable */ + DataNum = sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEEDataNum; + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEEWriteAddr = (uint32_t)((uint16_t)WriteAddr); + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEEpBuffer = pBuffer; + + /* If there are remaining data to transfer */ + if ((sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENumOfPage != 0) + || (sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENumOfSingle != 0)) + { + /* update global variable */ + sEE_WriteStructures[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]->sEENextWrite = 1; + } + + /* Write data on EEPROM */ + if (sEE_WritePage(sEEInitStruct, pBuffer, WriteAddr, DataNum) != CPAL_PASS) + { + return CPAL_FAIL; + } + + } + return CPAL_PASS; + } + else + { + return CPAL_FAIL; + } +} + +/** + * @brief Handle EEPROM Write operation + * @param Device : sEE CPAL device instance + * @retval None + */ +uint32_t sEE_WriteHandler(CPAL_DevTypeDef Device) +{ + uint32_t DataNum = 0; + + /* wait until EEPROM ready for transfer */ + while (sEE_WaitEepromStandbyState(Device) == CPAL_FAIL); + + /* if there are remaining data for write */ + if (sEE_WriteStructures[Device]->sEENextWrite != 0) + { + sEE_WriteStructures[Device]->sEEWriteAddr += sEE_WriteStructures[Device]->sEEDataNum; + sEE_WriteStructures[Device]->sEEpBuffer += sEE_WriteStructures[Device]->sEEDataNum; + sEE_WriteStructures[Device]->sEENextWrite = 0; + + /* if page must be written in EEPROM */ + if(sEE_WriteStructures[Device]->sEENumOfPage != 0) + { + sEE_WriteStructures[Device]->sEEDataNum = (uint32_t)((uint16_t)sEE_DevStructures[Device]->sEEPageSize); + sEE_WriteStructures[Device]->sEENumOfPage--; + } + /* if single byte must be written in EEPROM */ + else if (sEE_WriteStructures[Device]->sEENumOfSingle != 0) + { + sEE_WriteStructures[Device]->sEEDataNum = (uint32_t)((uint8_t)sEE_WriteStructures[Device]->sEENumOfSingle); + sEE_WriteStructures[Device]->sEENumOfSingle = 0; + sEE_WriteStructures[Device]->sEENextWrite = 0; + } + + /* update number of date for write */ + DataNum = sEE_WriteStructures[Device]->sEEDataNum; + + /* if another data must be written */ + if ((sEE_WriteStructures[Device]->sEENumOfPage != 0) + || (sEE_WriteStructures[Device]->sEENumOfSingle != 0)) + { + sEE_WriteStructures[Device]->sEENextWrite = 1; + } + + /* write data in EEPROM */ + sEE_WritePage(sEE_DevStructures[Device],(uint8_t*)sEE_WriteStructures[Device]->sEEpBuffer, \ + sEE_WriteStructures[Device]->sEEWriteAddr, DataNum); + } + else + { + if (sEE_DevStructures[Device]->sEEState != sEE_STATE_ERROR) + { + /* Reset EEPROM State */ + sEE_DevStructures[Device]->sEEState = sEE_STATE_IDLE; + } + } + + return CPAL_PASS; +} + + +/** + * @brief Handle EEPROM Read operation + * @param Device : sEE CPAL device instance + * @retval None + */ +uint32_t sEE_ReadHandler(CPAL_DevTypeDef Device) +{ + if (sEE_DevStructures[Device]->sEEState != sEE_STATE_ERROR) + { + /* Reset EEPROM State */ + sEE_DevStructures[Device]->sEEState = sEE_STATE_IDLE; + } + + return CPAL_PASS; +} + + +/** + * @brief Writes more than one byte to the EEPROM with a single WRITE cycle. + * @note The number of byte can't exceed the EEPROM page size. + * @param sEEInitStruct : Pointer to sEE Device structure + * @param pBuffer : pointer to the buffer containing the data to be written to + * the EEPROM. + * @param WriteAddr : EEPROM's internal address to write to. + * @param NumByteToWrite : pointer to the variable holding number of bytes to + * written to the EEPROM. + * + * @note The variable pointed by NumByteToWrite is reset to 0 when all the + * data are read from the EEPROM. Application should monitor this + * variable in order know when the transfer is complete. + * + * @note When number of data to be written is higher than 1, this function just + * configure the communication and enable the DMA channel to transfer data. + * Meanwhile, the user application may perform other tasks. + * When number of data to be written is 1, then the DMA is not used. + * + * @retval None + */ +static uint32_t sEE_WritePage(sEE_InitTypeDef* sEEInitStruct, uint8_t* pBuffer, \ + uint16_t WriteAddr, uint32_t NumByteToWrite) +{ + sEEInitStruct->sEE_CPALStructure->wCPAL_Options = 0; + + /* Enable 16Bit memory register option on CPAL */ + if (sEEInitStruct->sEEMemoryAddrMode & sEE_OPT_16BIT_REG) + { + sEEInitStruct->sEE_CPALStructure->wCPAL_Options = CPAL_OPT_16BIT_REG; + } + + sEEInitStruct->sEE_CPALStructure->pCPAL_TransferTx = sEE_TXTransfer[sEEInitStruct->sEE_CPALStructure->CPAL_Dev]; + + /* Configure transfer parameters */ + sEEInitStruct->sEE_CPALStructure->pCPAL_TransferTx->wNumData = (uint32_t)(NumByteToWrite); + sEEInitStruct->sEE_CPALStructure->pCPAL_TransferTx->pbBuffer = pBuffer; + sEEInitStruct->sEE_CPALStructure->pCPAL_TransferTx->wAddr1 = (uint32_t)((uint8_t)sEEInitStruct->sEEAddress); + sEEInitStruct->sEE_CPALStructure->pCPAL_TransferTx->wAddr2 = (uint32_t)((uint16_t)WriteAddr); + + /* Write Operation */ + return CPAL_I2C_Write(sEEInitStruct->sEE_CPALStructure); + +} + +/** + * @brief Wait for EEPROM Standby state + * @param Device : sEE CPAL device instance + * @retval None + */ +uint32_t sEE_WaitEepromStandbyState(CPAL_DevTypeDef Device) +{ + sEE_DevStructures[Device]->sEE_CPALStructure->pCPAL_TransferTx = sEE_TXTransfer[Device]; + sEE_DevStructures[Device]->sEE_CPALStructure->pCPAL_TransferTx->wAddr1 = \ + (uint32_t)((uint8_t)sEE_DevStructures[Device]->sEEAddress); + + return CPAL_I2C_IsDeviceReady(sEE_DevStructures[Device]->sEE_CPALStructure); +} + + +/** + * @brief Wait for EEPROM Standby state + * @param sEEInitStruct : Pointer to sEE Device structure + * @retval None + */ +uint32_t sEE_GetEepromState(sEE_InitTypeDef* sEEInitStruct) +{ + return sEEInitStruct->sEEState; +} + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee_cpal.h b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee_cpal.h new file mode 100644 index 0000000..32b14e9 --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_i2c_ee_cpal.h @@ -0,0 +1,231 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_i2c_ee_cpal.h + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file contains all the functions prototypes for + * the stm32303c_eval_i2c_ee_cpal.c firmware driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32303C_EVAL_I2C_EE_CPAL_H +#define __STM32303C_EVAL_I2C_EE_CPAL_H + +#ifdef __cplusplus + extern "C" { +#endif + + +/*=================================================================================== + User NOTES +===================================================================================== + +--------------------------------- + How To use the EEPROM Driver: +--------------------------------- +----- All EEPROM operations are controlled and monitored through a single + structure. This structure holds all necessary parameters to manage EEPROM + communication (pointer to CPAL I2C device structure, EEPROM address, + EEPROM page size, EEPROM memory addressing mode, EEPROM state). + +----- User should follow these steps to use this driver correctly : + + -1- STRUCTURE INITIALIZATION + Start by initializing the structure holding EEPROM Information. To perform + this action, the global variable sEEx_DevStructure declared in EEPROM driver + as sEE_InitTypeDef (sEE1_DevStructure for EEPROM connected with I2C1, + sEE2_DevStructure for EEPROM connected with I2C1 ...) must be used. + + sEE_InitTypeDef structure contains five parameters: + + *- CPAL_InitTypeDef* sEE_CPALStructure : Pointer on a CPAL Device structure + relative to the device instantiated + to communicate with EEPROM. + + *- uint32_t sEEAddress : Contains the EEPROM device Address. + + *- uint32_t sEEPageSize : Contains the page size of EEPROM Memory. + + *- uint8_t sEEMemoryAddrMode : Bit-field value specifying Memory Addressing Mode. + + *- __IO sEE_StateTypeDef sEEState : Holds the current State of the EEPROM device. + + To configure this structure, user must initialize only three parameters + (sEEAddress, sEEPageSize, sEEMemoryAddrMode). + + Example: + sEE1_DevStructure.sEEAddress = 0xA0; // set EEPROM address to 0xA0 + sEE1_DevStructure.sEEPageSize = 32; // set page size to 32 + sEE1_DevStructure.sEEMemoryAddrMode = sEE_OPT_16BIT_REG; // enable 16Bit memory addressing mode + + -2- DEVICE CONFIGURATION + Call the function sEE_StructInit() to initialize I2Cx CPAL device structure + relative to EEPROM than call sEE_Init() to configure the selected device + with the selected configuration. + + -3- READ / WRITE OPERATIONS + Call the function sEE_WriteBuffer() or sEE_ReadBuffer() to perform transfer operations. + These functions start data transfer and exit. sEE_WriteHandler() and sEE_ReadHandler() + handle the remainder of the communication. sEE_WriteHandler() must be called in + CPAL_I2C_TXTC_UserCallback() and sEE_ReadHandler() must be called in CPAL_I2C_RXTC_UserCallback(). + These two callbacks are implemented in "cpal_usercallback.c" file. + + Example of how to implement sEE_WriteHandler() in CPAL_I2C_TXTC_UserCallback(): + + 1** Comment "#define CPAL_I2C_TXTC_UserCallback (void)" in cpal_conf.h. + 2** Implement CPAL_I2C_TXTC_UserCallback in "cpal_usercallback.c" file. + + void CPAL_I2C_TXTC_UserCallback(CPAL_InitTypeDef* pDevInitStruct) + { + sEE_WriteHandler(pDevInitStruct->CPAL_Dev); + } + + User should monitor transfer by testing the value of sEEState parameter of + sEEx_DevStructure. When transfer is ongoing sEEState is equal to sEE_STATE_WRITING + or sEE_STATE_READING. After transfer complete this parameter is set to sEE_STATE_IDLE. + + Example of how to wait until EEPROM communication finishes: + + while(sEE_GetEepromState(&sEE_DevStructure) != sEE_STATE_IDLE) + { + //Application may perform other tasks while transfer operation is ongoing + } + + -4- DEVICE DEINITIALIZATION + When transfer operations are finished, you may call sEE_DeInit() to disable I2Cx device + and related resources (GPIO, DMA , IT and NVIC) relative to used EEPROM. + +*****************************END OF User Notes**********************************************/ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f30x_i2c_cpal.h" + +/* Exported types ------------------------------------------------------------*/ + +/*========= sEE_State_Enum =========*/ +/* sEE global State enumeration contains the current state of EEPROM. + Before starting each operation this state is tested. After each operation + sEE_State is updated with the new value resulting from the relative operation.*/ + + typedef enum +{ + sEE_STATE_IDLE = 0x01, /*!<This state indicates that the EEPROM device is in idle state */ + + sEE_STATE_WRITING = 0x02, /*!<This state indicates that write operation is ongoing */ + + sEE_STATE_READING = 0x03, /*!<This state indicates that read operation is ongoing */ + + sEE_STATE_ERROR = 0x04, /*!<This state indicates that an error is occurred during + last operation */ + +}sEE_StateTypeDef; + + +/*========= CPAL_sEE_TypeDef =========*/ +/* sEE Device structure definition */ +typedef struct +{ + CPAL_InitTypeDef* sEE_CPALStructure; /*!< Pointer on a CPAL Device structure relative to the device + instantiated to communicate with EEPROM */ + + uint16_t sEEPageSize; /*!< Contains the page size of EEPROM Memory*/ + + uint8_t sEEAddress; /*!< Contains the EEPROM device Address */ + + + uint8_t sEEMemoryAddrMode; /*!< Bit-field value specifying Memory Addressing Mode. Can be + any combination of following values: + sEE_Memory_Addressing_Mode_Defines */ + + __IO sEE_StateTypeDef sEEState; /*!< Holds the current State of the EEPROM device. The state + parameter can be one of the following values: sEE_State_Enum */ + +} sEE_InitTypeDef; + + +/*========= sEE_Global_Device_Structures =========*/ +/* sEE Global Device Structures are the Global default structures which + are used to handle sEE configuration and status.*/ + +extern sEE_InitTypeDef* sEE_DevStructures[]; + +#ifdef CPAL_USE_I2C1 +extern sEE_InitTypeDef sEE1_DevStructure; +#endif /* CPAL_USE_I2C1 */ + +#ifdef CPAL_USE_I2C2 +extern sEE_InitTypeDef sEE2_DevStructure; +#endif /* CPAL_USE_I2C2 */ + +/* Exported constants --------------------------------------------------------*/ + +/*============== TIMING Configuration ==========================*/ +/* I2C TIMING Register define */ +/* I2C TIMING is calculated in case of the I2C Clock source is the SYSCLK = 72 MHz */ +/* When using sEE_M24M01 set TIMING to 0x00C4092A to reach 1 MHz speed (Rise time = 26ns, Fall time = 2ns) */ +/* When using sEE_M24LR64 set TIMING to 0xC062121F to reach 100 KHz speed (Rise time = 640ns, Fall time = 20ns) */ + +#define sEE_I2C_TIMING 0xC062121F + + +/*============== Programming model Configuration ==========================*/ +/* Select interrupt programming model : By default DMA programming model is selected. + To select interrupt programming model uncomment this define */ +//#define sEE_IT + +/*========= sEE_Memory_Addressing_Mode_Defines =========*/ +/* sEE Memory_Addressing_Mode defines can be affected to sEEMemoryAddrMode which is + a bit-field argument so any combination of these parameters can be selected. + If one option is not selected then the relative feature is disabled.*/ + + +#define sEE_OPT_NO_MEM_ADDR ((uint8_t)0x01) /*!<Enable No Memory addressing mode for read operation : only EEPROM + device address sent. No Register/Physical address to be sent after + addressing phase */ + +#define sEE_OPT_16BIT_REG ((uint8_t)0x02) /*!<Enable 16-Bit Register/Physical addressing mode (two bytes, + MSB first). This option is supported only when sEE_OPT_NO_MEM_ADDR + option is not set */ + + + +/* Exported macro ------------------------------------------------------------*/ +/* Exported functions ------------------------------------------------------- */ + +void sEE_DeInit(sEE_InitTypeDef* sEEInitStruct); +void sEE_Init(sEE_InitTypeDef* sEEInitStruct); +void sEE_StructInit(sEE_InitTypeDef* sEEInitStruct); +uint32_t sEE_WriteBuffer(sEE_InitTypeDef* sEEInitStruct, uint8_t* pBuffer, uint16_t WriteAddr, uint32_t NumByteToWrite); +uint32_t sEE_WriteHandler(CPAL_DevTypeDef Device); +uint32_t sEE_ReadBuffer(sEE_InitTypeDef* sEEInitStruct, uint8_t* pBuffer, uint16_t ReadAddr, uint32_t NumByteToRead); +uint32_t sEE_ReadHandler(CPAL_DevTypeDef Device); +uint32_t sEE_WaitEepromStandbyState(CPAL_DevTypeDef Device); +uint32_t sEE_GetEepromState(sEE_InitTypeDef* sEEInitStruct); + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32303C_EVAL_I2C_EE_CPAL_H */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_lcd.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_lcd.c new file mode 100644 index 0000000..ad19e6a --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_lcd.c @@ -0,0 +1,1746 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_lcd.c + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file includes the LCD driver for AM-240320L8TNQW00H (ILI9320), + * AM-240320LDTNQW00H (SPFD5408B) and AM240320LGTNQW00H (HX8347D) + * Liquid Crystal Display Module of STM32303C-EVAL board. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval_lcd.h" +#include "../Common/fonts.c" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @defgroup STM32303C_EVAL_LCD + * @brief This file includes the LCD driver for AM-240320L8TNQW00H (ILI9320), + * AM-240320LDTNQW00H (SPFD5408B) and AM240320LGTNQW00H (HX8347D) + * Liquid Crystal Display Module of STM32303C-EVAL board. + * @{ + */ + +/** @defgroup STM32303C_EVAL_LCD_Private_Types + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_LCD_Private_Defines + * @{ + */ +#define START_BYTE 0x70 +#define SET_INDEX 0x00 +#define READ_STATUS 0x01 +#define LCD_WRITE_REG 0x02 +#define LCD_READ_REG 0x03 +#define MAX_POLY_CORNERS 200 +#define POLY_Y(Z) ((int32_t)((Points + Z)->X)) +#define POLY_X(Z) ((int32_t)((Points + Z)->Y)) +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_LCD_Private_Macros + * @{ + */ +#define ABS(X) ((X) > 0 ? (X) : -(X)) +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_LCD_Private_Variables + * @{ + */ +static sFONT *LCD_Currentfonts; +/* Global variables to set the written text color */ +static __IO uint16_t TextColor = 0x0000, BackColor = 0xFFFF; +__IO uint32_t LCDType = 0; + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_LCD_Private_Function_Prototypes + * @{ + */ +#ifndef USE_Delay +static void delay(__IO uint32_t nCount); +#endif /* USE_Delay*/ + +static void PutPixel(int16_t x, int16_t y); +static void LCD_PolyLineRelativeClosed(pPoint Points, uint16_t PointCount, uint16_t Closed); + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_LCD_Private_Functions + * @{ + */ + +/** + * @brief DeInitializes the LCD. + * @param None + * @retval None + */ +void LCD_DeInit(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + /*!< LCD Display Off */ + LCD_DisplayOff(); + + /*!< LCD_SPI disable */ + SPI_Cmd(LCD_SPI, DISABLE); + + /*!< LCD_SPI DeInit */ + SPI_I2S_DeInit(LCD_SPI); + + /*!< Disable SPI clock */ + RCC_APB1PeriphClockCmd(LCD_SPI_CLK, DISABLE); + + /* Configure NCS in Output Push-Pull mode */ + GPIO_InitStructure.GPIO_Pin = LCD_NCS_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(LCD_NCS_GPIO_PORT, &GPIO_InitStructure); + + /* Configure SPI pins: SCK, MISO and MOSI */ + GPIO_InitStructure.GPIO_Pin = LCD_SPI_SCK_PIN; + GPIO_Init(LCD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = LCD_SPI_MISO_PIN; + GPIO_Init(LCD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure); + + GPIO_InitStructure.GPIO_Pin = LCD_SPI_MOSI_PIN; + GPIO_Init(LCD_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); +} + +/** + * @brief Setups the LCD. + * @param None + * @retval None + */ +void LCD_Setup(void) +{ +/* Configure the LCD Control pins --------------------------------------------*/ + LCD_CtrlLinesConfig(); + +/* Configure the LCD_SPI interface ----------------------------------------------*/ + LCD_SPIConfig(); + + if(LCDType == LCD_ILI9320) + { + _delay_(5); /* Delay 50 ms */ + /* Start Initial Sequence ------------------------------------------------*/ + LCD_WriteReg(LCD_REG_229, 0x8000); /* Set the internal vcore voltage */ + LCD_WriteReg(LCD_REG_0, 0x0001); /* Start internal OSC. */ + LCD_WriteReg(LCD_REG_1, 0x0100); /* set SS and SM bit */ + LCD_WriteReg(LCD_REG_2, 0x0700); /* set 1 line inversion */ + LCD_WriteReg(LCD_REG_3, 0x1030); /* set GRAM write direction and BGR=1. */ + LCD_WriteReg(LCD_REG_4, 0x0000); /* Resize register */ + LCD_WriteReg(LCD_REG_8, 0x0202); /* set the back porch and front porch */ + LCD_WriteReg(LCD_REG_9, 0x0000); /* set non-display area refresh cycle ISC[3:0] */ + LCD_WriteReg(LCD_REG_10, 0x0000); /* FMARK function */ + LCD_WriteReg(LCD_REG_12, 0x0000); /* RGB interface setting */ + LCD_WriteReg(LCD_REG_13, 0x0000); /* Frame marker Position */ + LCD_WriteReg(LCD_REG_15, 0x0000); /* RGB interface polarity */ + /* Power On sequence -----------------------------------------------------*/ + LCD_WriteReg(LCD_REG_16, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ + LCD_WriteReg(LCD_REG_17, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */ + LCD_WriteReg(LCD_REG_18, 0x0000); /* VREG1OUT voltage */ + LCD_WriteReg(LCD_REG_19, 0x0000); /* VDV[4:0] for VCOM amplitude */ + _delay_(20); /* Dis-charge capacitor power voltage (200ms) */ + LCD_WriteReg(LCD_REG_16, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ + LCD_WriteReg(LCD_REG_17, 0x0137); /* DC1[2:0], DC0[2:0], VC[2:0] */ + _delay_(5); /* Delay 50 ms */ + LCD_WriteReg(LCD_REG_18, 0x0139); /* VREG1OUT voltage */ + _delay_(5); /* Delay 50 ms */ + LCD_WriteReg(LCD_REG_19, 0x1d00); /* VDV[4:0] for VCOM amplitude */ + LCD_WriteReg(LCD_REG_41, 0x0013); /* VCM[4:0] for VCOMH */ + _delay_(5); /* Delay 50 ms */ + LCD_WriteReg(LCD_REG_32, 0x0000); /* GRAM horizontal Address */ + LCD_WriteReg(LCD_REG_33, 0x0000); /* GRAM Vertical Address */ + /* Adjust the Gamma Curve ------------------------------------------------*/ + LCD_WriteReg(LCD_REG_48, 0x0006); + LCD_WriteReg(LCD_REG_49, 0x0101); + LCD_WriteReg(LCD_REG_50, 0x0003); + LCD_WriteReg(LCD_REG_53, 0x0106); + LCD_WriteReg(LCD_REG_54, 0x0b02); + LCD_WriteReg(LCD_REG_55, 0x0302); + LCD_WriteReg(LCD_REG_56, 0x0707); + LCD_WriteReg(LCD_REG_57, 0x0007); + LCD_WriteReg(LCD_REG_60, 0x0600); + LCD_WriteReg(LCD_REG_61, 0x020b); + + /* Set GRAM area ---------------------------------------------------------*/ + LCD_WriteReg(LCD_REG_80, 0x0000); /* Horizontal GRAM Start Address */ + LCD_WriteReg(LCD_REG_81, 0x00EF); /* Horizontal GRAM End Address */ + LCD_WriteReg(LCD_REG_82, 0x0000); /* Vertical GRAM Start Address */ + LCD_WriteReg(LCD_REG_83, 0x013F); /* Vertical GRAM End Address */ + LCD_WriteReg(LCD_REG_96, 0x2700); /* Gate Scan Line */ + LCD_WriteReg(LCD_REG_97, 0x0001); /* NDL,VLE, REV */ + LCD_WriteReg(LCD_REG_106, 0x0000); /* set scrolling line */ + /* Partial Display Control -----------------------------------------------*/ + LCD_WriteReg(LCD_REG_128, 0x0000); + LCD_WriteReg(LCD_REG_129, 0x0000); + LCD_WriteReg(LCD_REG_130, 0x0000); + LCD_WriteReg(LCD_REG_131, 0x0000); + LCD_WriteReg(LCD_REG_132, 0x0000); + LCD_WriteReg(LCD_REG_133, 0x0000); + /* Panel Control ---------------------------------------------------------*/ + LCD_WriteReg(LCD_REG_144, 0x0010); + LCD_WriteReg(LCD_REG_146, 0x0000); + LCD_WriteReg(LCD_REG_147, 0x0003); + LCD_WriteReg(LCD_REG_149, 0x0110); + LCD_WriteReg(LCD_REG_151, 0x0000); + LCD_WriteReg(LCD_REG_152, 0x0000); + /* Set GRAM write direction and BGR = 1 */ + /* I/D=01 (Horizontal : increment, Vertical : decrement) */ + /* AM=1 (address is updated in vertical writing direction) */ + LCD_WriteReg(LCD_REG_3, 0x1018); + LCD_WriteReg(LCD_REG_7, 0x0173); /* 262K color and display ON */ + } + else if(LCDType == LCD_SPFD5408) + { + /* Start Initial Sequence --------------------------------------------------*/ + LCD_WriteReg(LCD_REG_227, 0x3008); /* Set internal timing */ + LCD_WriteReg(LCD_REG_231, 0x0012); /* Set internal timing */ + LCD_WriteReg(LCD_REG_239, 0x1231); /* Set internal timing */ + LCD_WriteReg(LCD_REG_1, 0x0100); /* Set SS and SM bit */ + LCD_WriteReg(LCD_REG_2, 0x0700); /* Set 1 line inversion */ + LCD_WriteReg(LCD_REG_3, 0x1030); /* Set GRAM write direction and BGR=1. */ + LCD_WriteReg(LCD_REG_4, 0x0000); /* Resize register */ + LCD_WriteReg(LCD_REG_8, 0x0202); /* Set the back porch and front porch */ + LCD_WriteReg(LCD_REG_9, 0x0000); /* Set non-display area refresh cycle ISC[3:0] */ + LCD_WriteReg(LCD_REG_10, 0x0000); /* FMARK function */ + LCD_WriteReg(LCD_REG_12, 0x0000); /* RGB interface setting */ + LCD_WriteReg(LCD_REG_13, 0x0000); /* Frame marker Position */ + LCD_WriteReg(LCD_REG_15, 0x0000); /* RGB interface polarity */ + /* Power On sequence -------------------------------------------------------*/ + LCD_WriteReg(LCD_REG_16, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ + LCD_WriteReg(LCD_REG_17, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */ + LCD_WriteReg(LCD_REG_18, 0x0000); /* VREG1OUT voltage */ + LCD_WriteReg(LCD_REG_19, 0x0000); /* VDV[4:0] for VCOM amplitude */ + _delay_(20); /* Dis-charge capacitor power voltage (200ms) */ + LCD_WriteReg(LCD_REG_17, 0x0007); /* DC1[2:0], DC0[2:0], VC[2:0] */ + _delay_(5); /* Delay 50 ms */ + LCD_WriteReg(LCD_REG_16, 0x12B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ + _delay_(5); /* Delay 50 ms */ + LCD_WriteReg(LCD_REG_18, 0x01BD); /* External reference voltage= Vci */ + _delay_(5); /* Delay 50 ms */ + LCD_WriteReg(LCD_REG_19, 0x1400); /* VDV[4:0] for VCOM amplitude */ + LCD_WriteReg(LCD_REG_41, 0x000E); /* VCM[4:0] for VCOMH */ + _delay_(5); /* Delay 50 ms */ + LCD_WriteReg(LCD_REG_32, 0x0000); /* GRAM horizontal Address */ + LCD_WriteReg(LCD_REG_33, 0x013F); /* GRAM Vertical Address */ + /* Adjust the Gamma Curve --------------------------------------------------*/ + LCD_WriteReg(LCD_REG_48, 0x0007); + LCD_WriteReg(LCD_REG_49, 0x0302); + LCD_WriteReg(LCD_REG_50, 0x0105); + LCD_WriteReg(LCD_REG_53, 0x0206); + LCD_WriteReg(LCD_REG_54, 0x0808); + LCD_WriteReg(LCD_REG_55, 0x0206); + LCD_WriteReg(LCD_REG_56, 0x0504); + LCD_WriteReg(LCD_REG_57, 0x0007); + LCD_WriteReg(LCD_REG_60, 0x0105); + LCD_WriteReg(LCD_REG_61, 0x0808); + /* Set GRAM area -----------------------------------------------------------*/ + LCD_WriteReg(LCD_REG_80, 0x0000); /* Horizontal GRAM Start Address */ + LCD_WriteReg(LCD_REG_81, 0x00EF); /* Horizontal GRAM End Address */ + LCD_WriteReg(LCD_REG_82, 0x0000); /* Vertical GRAM Start Address */ + LCD_WriteReg(LCD_REG_83, 0x013F); /* Vertical GRAM End Address */ + LCD_WriteReg(LCD_REG_96, 0xA700); /* Gate Scan Line */ + LCD_WriteReg(LCD_REG_97, 0x0001); /* NDL,VLE, REV */ + LCD_WriteReg(LCD_REG_106, 0x0000); /* Set scrolling line */ + /* Partial Display Control -------------------------------------------------*/ + LCD_WriteReg(LCD_REG_128, 0x0000); + LCD_WriteReg(LCD_REG_129, 0x0000); + LCD_WriteReg(LCD_REG_130, 0x0000); + LCD_WriteReg(LCD_REG_131, 0x0000); + LCD_WriteReg(LCD_REG_132, 0x0000); + LCD_WriteReg(LCD_REG_133, 0x0000); + /* Panel Control -----------------------------------------------------------*/ + LCD_WriteReg(LCD_REG_144, 0x0010); + LCD_WriteReg(LCD_REG_146, 0x0000); + LCD_WriteReg(LCD_REG_147, 0x0003); + LCD_WriteReg(LCD_REG_149, 0x0110); + LCD_WriteReg(LCD_REG_151, 0x0000); + LCD_WriteReg(LCD_REG_152, 0x0000); + /* Set GRAM write direction and BGR = 1 + I/D=01 (Horizontal : increment, Vertical : decrement) + AM=1 (address is updated in vertical writing direction) */ + LCD_WriteReg(LCD_REG_3, 0x1018); + LCD_WriteReg(LCD_REG_7, 0x0112); /* 262K color and display ON */ + } + else if(LCDType == LCD_HX8347D) + { + /* Driving ability setting */ + LCD_WriteReg(LCD_REG_234, 0x00); + LCD_WriteReg(LCD_REG_235, 0x20); + LCD_WriteReg(LCD_REG_236, 0x0C); + LCD_WriteReg(LCD_REG_237, 0xC4); + LCD_WriteReg(LCD_REG_232, 0x40); + LCD_WriteReg(LCD_REG_233, 0x38); + LCD_WriteReg(LCD_REG_241, 0x01); + LCD_WriteReg(LCD_REG_242, 0x10); + LCD_WriteReg(LCD_REG_39, 0xA3); + + /* Adjust the Gamma Curve */ + LCD_WriteReg(LCD_REG_64, 0x01); + LCD_WriteReg(LCD_REG_65, 0x00); + LCD_WriteReg(LCD_REG_66, 0x00); + LCD_WriteReg(LCD_REG_67, 0x10); + LCD_WriteReg(LCD_REG_68, 0x0E); + LCD_WriteReg(LCD_REG_69, 0x24); + LCD_WriteReg(LCD_REG_70, 0x04); + LCD_WriteReg(LCD_REG_71, 0x50); + LCD_WriteReg(LCD_REG_72, 0x02); + LCD_WriteReg(LCD_REG_73, 0x13); + LCD_WriteReg(LCD_REG_74, 0x19); + LCD_WriteReg(LCD_REG_75, 0x19); + LCD_WriteReg(LCD_REG_76, 0x16); + LCD_WriteReg(LCD_REG_80, 0x1B); + LCD_WriteReg(LCD_REG_81, 0x31); + LCD_WriteReg(LCD_REG_82, 0x2F); + LCD_WriteReg(LCD_REG_83, 0x3F); + LCD_WriteReg(LCD_REG_84, 0x3F); + LCD_WriteReg(LCD_REG_85, 0x3E); + LCD_WriteReg(LCD_REG_86, 0x2F); + LCD_WriteReg(LCD_REG_87, 0x7B); + LCD_WriteReg(LCD_REG_88, 0x09); + LCD_WriteReg(LCD_REG_89, 0x06); + LCD_WriteReg(LCD_REG_90, 0x06); + LCD_WriteReg(LCD_REG_91, 0x0C); + LCD_WriteReg(LCD_REG_92, 0x1D); + LCD_WriteReg(LCD_REG_93, 0xCC); + + /* Power voltage setting */ + LCD_WriteReg(LCD_REG_27, 0x1B); + LCD_WriteReg(LCD_REG_26, 0x01); + LCD_WriteReg(LCD_REG_36, 0x2F); + LCD_WriteReg(LCD_REG_37, 0x57); + /*****VCOM offset ****/ + LCD_WriteReg(LCD_REG_35, 0x86); + + /* Power on setting up flow */ + LCD_WriteReg(LCD_REG_24, 0x36); /* Display frame rate = 70Hz RADJ = '0110' */ + LCD_WriteReg(LCD_REG_25, 0x01); /* OSC_EN = 1 */ + LCD_WriteReg(LCD_REG_28, 0x06); /* AP[2:0] = 111 */ + LCD_WriteReg(LCD_REG_29, 0x06); /* AP[2:0] = 111 */ + LCD_WriteReg(LCD_REG_31,0x90); /* GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0*/ + LCD_WriteReg(LCD_REG_39, 1); /* REF = 1 */ + _delay_(10); + + /* 262k/65k color selection */ + LCD_WriteReg(LCD_REG_23, 0x05); /* default 0x06 262k color, 0x05 65k color */ + /* SET PANEL */ + LCD_WriteReg(LCD_REG_54, 0x09); /* SS_PANEL = 1, GS_PANEL = 0,REV_PANEL = 0, BGR_PANEL = 1 */ + + /* Display ON flow */ + LCD_WriteReg(LCD_REG_40, 0x38); /* GON=1, DTE=1, D=10 */ + _delay_(60); + LCD_WriteReg(LCD_REG_40, 0x3C); /* GON=1, DTE=1, D=11 */ + + /* Set GRAM Area - Partial Display Control */ + LCD_WriteReg(LCD_REG_1, 0x00); /* DP_STB = 0, DP_STB_S = 0, SCROLL = 0, */ + LCD_WriteReg(LCD_REG_2, 0x00); /* Column address start 2 */ + LCD_WriteReg(LCD_REG_3, 0x00); /* Column address start 1 */ + LCD_WriteReg(LCD_REG_4, 0x01); /* Column address end 2 */ + LCD_WriteReg(LCD_REG_5, 0x3F); /* Column address end 1 */ + LCD_WriteReg(LCD_REG_6, 0x00); /* Row address start 2 */ + LCD_WriteReg(LCD_REG_7, 0x00); /* Row address start 2 */ + LCD_WriteReg(LCD_REG_8, 0x00); /* Row address end 2 */ + LCD_WriteReg(LCD_REG_9, 0xEF); /* Row address end 1 */ + LCD_WriteReg(LCD_REG_22, 0xE0); /* Memory access control: MY = 1, MX = 0, MV = 1, ML = 0 */ + } + /* Set default font */ + LCD_SetFont(&LCD_DEFAULT_FONT); +} + +/** + * @brief Swap the display direction. This is useful when displaying bmp files. + * @param None. + * @retval None + */ +void LCD_SwapDirection(FunctionalState NewState) +{ + if (NewState != DISABLE) + { + if(LCDType == LCD_HX8347D) + { + /* Memory access control: MY = 1, MX = 0, MV = 1, ML = 0 */ + LCD_WriteReg(LCD_REG_22, 0xA0); + } + else + { + /* Set GRAM write direction and BGR = 1 */ + /* I/D=00 (Horizontal : decrement, Vertical : decrement) */ + /* AM=1 (address is updated in vertical writing direction) */ + LCD_WriteReg(LCD_REG_3, 0x1008); + } + } + else + { + if(LCDType == LCD_HX8347D) + { + /* Memory access control: MY = 1, MX = 1, MV = 1, ML = 0 */ + LCD_WriteReg(LCD_REG_22, 0xE0); + } + else + { + /* Set GRAM write direction and BGR = 1 */ + /* I/D=00 (Horizontal : decrement, Vertical : decrement) */ + /* AM=1 (address is updated in vertical writing direction) */ + LCD_WriteReg(LCD_REG_3, 0x1018); + } + } +} + +/** + * @brief Initializes the LCD. + * @param None + * @retval None + */ +void STM32303C_LCD_Init(void) +{ + __IO uint32_t lcdid = 0; + + /* Setups the LCD */ + LCD_Setup(); + + /* Read the LCD ID */ + lcdid = LCD_ReadReg(0x00); + + if (lcdid == LCD_SPFD5408) + { + LCDType = LCD_SPFD5408; + /* Setups the LCD */ + LCD_Setup(); + } + else if (lcdid == LCD_ILI9320) + { + LCDType = LCD_ILI9320; + /* Setups the LCD */ + LCD_Setup(); + } + else + { + LCDType = LCD_HX8347D; + /* Setups the LCD */ + LCD_Setup(); + } + + LCD_SetFont(&LCD_DEFAULT_FONT); +} + +/** + * @brief Sets the LCD Text and Background colors. + * @param _TextColor: specifies the Text Color. + * @param _BackColor: specifies the Background Color. + * @retval None + */ +void LCD_SetColors(__IO uint16_t _TextColor, __IO uint16_t _BackColor) +{ + TextColor = _TextColor; + BackColor = _BackColor; +} + +/** + * @brief Gets the LCD Text and Background colors. + * @param _TextColor: pointer to the variable that will contain the Text + Color. + * @param _BackColor: pointer to the variable that will contain the Background + Color. + * @retval None + */ +void LCD_GetColors(__IO uint16_t *_TextColor, __IO uint16_t *_BackColor) +{ + *_TextColor = TextColor; *_BackColor = BackColor; +} + +/** + * @brief Sets the Text color. + * @param Color: specifies the Text color code RGB(5-6-5). + * @retval None + */ +void LCD_SetTextColor(__IO uint16_t Color) +{ + TextColor = Color; +} + + +/** + * @brief Sets the Background color. + * @param Color: specifies the Background color code RGB(5-6-5). + * @retval None + */ +void LCD_SetBackColor(__IO uint16_t Color) +{ + BackColor = Color; +} + +/** + * @brief Sets the Text Font. + * @param fonts: specifies the font to be used. + * @retval None + */ +void LCD_SetFont(sFONT *fonts) +{ + LCD_Currentfonts = fonts; +} + +/** + * @brief Gets the Text Font. + * @param None. + * @retval the used font. + */ +sFONT *LCD_GetFont(void) +{ + return LCD_Currentfonts; +} + +/** + * @brief Clears the selected line. + * @param Line: the Line to be cleared. + * This parameter can be one of the following values: + * @arg Linex: where x can be 0..n + * @retval None + */ +void LCD_ClearLine(uint8_t Line) +{ + uint16_t refcolumn = 319; + int16_t deltacolumn = -LCD_Currentfonts->Width; + uint32_t i = 0; + + /* Send the string character by character on lCD */ + while (i <= 320/LCD_Currentfonts->Width) + { + /* Display one character on LCD */ + LCD_DisplayChar(Line, refcolumn, ' '); + /* Decrement the column position by deltacolumn(16) */ + refcolumn += deltacolumn; + /* Increment the character counter */ + i++; + } +} + + +/** + * @brief Clears the hole LCD. + * @param Color: the color of the background. + * @retval None + */ +void LCD_Clear(uint16_t Color) +{ + uint32_t index = 0; + + if(LCDType == LCD_HX8347D) + { + LCD_SetCursor(0, 0); + } + else + { + LCD_SetCursor(0, 319); + } + + /* Prepare to write GRAM */ + LCD_WriteRAM_Prepare(); + + for(index = 0; index < (uint32_t)320*240; index++) + { + LCD_WriteRAM(Color); + } + + /* Wait until a data is sent(not busy), before config /CS HIGH */ + while (SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET); + LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET); +} + + +/** + * @brief Sets the cursor position. + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @retval None + */ +void LCD_SetCursor(uint8_t Xpos, uint16_t Ypos) +{ + if(LCDType == LCD_HX8347D) + { + LCD_WriteReg(LCD_REG_6, 0x00); + LCD_WriteReg(LCD_REG_7, Xpos); + LCD_WriteReg(LCD_REG_2, Ypos >> 8); + LCD_WriteReg(LCD_REG_3, Ypos & 0xFF); + } + else + { + LCD_WriteReg(LCD_REG_32, Xpos); + LCD_WriteReg(LCD_REG_33, Ypos); + } +} + + +/** + * @brief Draws a character on LCD. + * @param Xpos: the Line where to display the character shape. + * @param Ypos: start column address. + * @param c: pointer to the character data. + * @retval None + */ +void LCD_DrawChar(uint8_t Xpos, uint16_t Ypos, const uint16_t *c) +{ + uint32_t index = 0, i = 0; + uint8_t Xaddress = 0; + + Xaddress = Xpos; + + LCD_SetCursor(Xaddress, Ypos); + + for(index = 0; index < LCD_Currentfonts->Height; index++) + { + LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */ + for(i = 0; i < LCD_Currentfonts->Width; i++) + { + if((((c[index] & ((0x80 << ((LCD_Currentfonts->Width / 12 ) * 8 ) ) >> i)) == 0x00) &&(LCD_Currentfonts->Width <= 12))|| + (((c[index] & (0x1 << i)) == 0x00)&&(LCD_Currentfonts->Width > 12 ))) + + { + LCD_WriteRAM(BackColor); + } + else + { + LCD_WriteRAM(TextColor); + } + } + LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET); + Xaddress++; + LCD_SetCursor(Xaddress, Ypos); + } +} + + +/** + * @brief Displays one character (16dots width, 24dots height). + * @param Line: the Line where to display the character shape . + * This parameter can be one of the following values: + * @arg Linex: where x can be 0..9 + * @param Column: start column address. + * @param Ascii: character ascii code, must be between 0x20 and 0x7E. + * @retval None + */ +void LCD_DisplayChar(uint8_t Line, uint16_t Column, uint8_t Ascii) +{ + Ascii -= 32; + + if(LCDType == LCD_HX8347D) + { + Column = 319 - Column; + } + + LCD_DrawChar(Line, Column, &LCD_Currentfonts->table[Ascii * LCD_Currentfonts->Height]); +} + + +/** + * @brief Displays a maximum of 20 char on the LCD. + * @param Line: the Line where to display the character shape . + * This parameter can be one of the following values: + * @arg Linex: where x can be 0..9 + * @param *ptr: pointer to string to display on LCD. + * @retval None + */ +void LCD_DisplayStringLine(uint8_t Line, uint8_t *ptr) +{ + uint16_t refcolumn = LCD_PIXEL_WIDTH - 1; + + /* Send the string character by character on lCD */ + while (*ptr != 0) + { + /* Display one character on LCD */ + LCD_DisplayChar(Line, refcolumn, *ptr); + /* Decrement the column position by 16 */ + refcolumn -= LCD_Currentfonts->Width; + /* Point on the next character */ + ptr++; + } +} + + +/** + * @brief Sets a display window + * @param Xpos: specifies the X buttom left position. + * @param Ypos: specifies the Y buttom left position. + * @param Height: display window height. + * @param Width: display window width. + * @retval None + */ +void LCD_SetDisplayWindow(uint8_t Xpos, uint16_t Ypos, uint8_t Height, uint16_t Width) +{ + if(LCDType == LCD_HX8347D) + { + LCD_WriteReg(LCD_REG_2, (319 - Ypos) >> 8); /* SC */ + LCD_WriteReg(LCD_REG_3, (319 - Ypos) & 0xFF); /* SC */ + + LCD_WriteReg(LCD_REG_4, (319 - (Ypos - Width + 1)) >> 8); /* EC */ + LCD_WriteReg(LCD_REG_5, (319 - (Ypos - Width + 1)) & 0xFF); /* EC */ + + LCD_WriteReg(LCD_REG_6, 0x0); /* SP */ + LCD_WriteReg(LCD_REG_7, (239 - Xpos) & 0xFF); /* SP */ + + LCD_WriteReg(LCD_REG_8, 0x0); /* EP */ + LCD_WriteReg(LCD_REG_9, (239 - (Xpos - Height + 1)) & 0xFF); /* EP */ + LCD_SetCursor(Xpos, Ypos); + } + else + { + /* Horizontal GRAM Start Address */ + if(Xpos >= Height) + { + LCD_WriteReg(LCD_REG_80, (Xpos - Height + 1)); + } + else + { + LCD_WriteReg(LCD_REG_80, 0); + } + /* Horizontal GRAM End Address */ + LCD_WriteReg(LCD_REG_81, Xpos); + /* Vertical GRAM Start Address */ + if(Ypos >= Width) + { + LCD_WriteReg(LCD_REG_82, (Ypos - Width + 1)); + } + else + { + LCD_WriteReg(LCD_REG_82, 0); + } + /* Vertical GRAM End Address */ + LCD_WriteReg(LCD_REG_83, Ypos); + } + LCD_SetCursor(Xpos, Ypos); +} + +/** + * @brief Disables LCD Window mode. + * @param None + * @retval None + */ +void LCD_WindowModeDisable(void) +{ + LCD_SetDisplayWindow(239, 0x13F, 240, 320); + + if(LCDType != LCD_HX8347D) + { + LCD_WriteReg(LCD_REG_3, 0x1018); + } +} + +/** + * @brief Displays a line. + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @param Length: line length. + * @param Direction: line direction. + * This parameter can be one of the following values: Vertical or Horizontal. + * @retval None + */ +void LCD_DrawLine(uint8_t Xpos, uint16_t Ypos, uint16_t Length, uint8_t Direction) +{ + uint32_t i = 0; + + if(LCDType == LCD_HX8347D) + { + LCD_SetCursor(Xpos, 319 - Ypos); + } + else + { + LCD_SetCursor(Xpos, Ypos); + } + + if(Direction == LCD_DIR_HORIZONTAL) + { + LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */ + + for(i = 0; i < Length; i++) + { + LCD_WriteRAM(TextColor); + } + /* Wait until a data is sent(not busy), before config /CS HIGH */ + while (SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET); + LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET); + } + else + { + for(i = 0; i < Length; i++) + { + LCD_WriteRAMWord(TextColor); + Xpos++; + if(LCDType == LCD_HX8347D) + { + LCD_SetCursor(Xpos, 319 - Ypos); + } + else + { + LCD_SetCursor(Xpos, Ypos); + } + } + } +} + + +/** + * @brief Displays a rectangle. + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @param Height: display rectangle height. + * @param Width: display rectangle width. + * @retval None + */ +void LCD_DrawRect(uint8_t Xpos, uint16_t Ypos, uint8_t Height, uint16_t Width) +{ + LCD_DrawLine(Xpos, Ypos, Width, LCD_DIR_HORIZONTAL); + LCD_DrawLine((Xpos + Height), Ypos, Width, LCD_DIR_HORIZONTAL); + + LCD_DrawLine(Xpos, Ypos, Height, LCD_DIR_VERTICAL); + LCD_DrawLine(Xpos, (Ypos - Width + 1), Height, LCD_DIR_VERTICAL); +} + + +/** + * @brief Displays a circle. + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @param Radius + * @retval None + */ +void LCD_DrawCircle(uint8_t Xpos, uint16_t Ypos, uint16_t Radius) +{ + int32_t D;/* Decision Variable */ + uint32_t CurX;/* Current X Value */ + uint32_t CurY;/* Current Y Value */ + + if(LCDType == LCD_HX8347D) + { + Ypos = 319 - Ypos; + } + + D = 3 - (Radius << 1); + CurX = 0; + CurY = Radius; + + while (CurX <= CurY) + { + LCD_SetCursor(Xpos + CurX, Ypos + CurY); + LCD_WriteRAMWord(TextColor); + + LCD_SetCursor(Xpos + CurX, Ypos - CurY); + LCD_WriteRAMWord(TextColor); + + LCD_SetCursor(Xpos - CurX, Ypos + CurY); + LCD_WriteRAMWord(TextColor); + + LCD_SetCursor(Xpos - CurX, Ypos - CurY); + LCD_WriteRAMWord(TextColor); + + LCD_SetCursor(Xpos + CurY, Ypos + CurX); + LCD_WriteRAMWord(TextColor); + + LCD_SetCursor(Xpos + CurY, Ypos - CurX); + LCD_WriteRAMWord(TextColor); + + LCD_SetCursor(Xpos - CurY, Ypos + CurX); + LCD_WriteRAMWord(TextColor); + + LCD_SetCursor(Xpos - CurY, Ypos - CurX); + LCD_WriteRAMWord(TextColor); + + if (D < 0) + { + D += (CurX << 2) + 6; + } + else + { + D += ((CurX - CurY) << 2) + 10; + CurY--; + } + CurX++; + } +} + + +/** + * @brief Displays a monocolor picture. + * @param Pict: pointer to the picture array. + * @retval None + */ +void LCD_DrawMonoPict(const uint32_t *Pict) +{ + uint32_t index = 0, i = 0; + + if(LCDType == LCD_HX8347D) + { + LCD_SetCursor(0, 0); + } + else + { + LCD_SetCursor(0, (LCD_PIXEL_WIDTH - 1)); + } + + LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */ + + for(index = 0; index < 2400; index++) + { + for(i = 0; i < 32; i++) + { + if((Pict[index] & (1 << i)) == 0x00) + { + LCD_WriteRAM(BackColor); + } + else + { + LCD_WriteRAM(TextColor); + } + } + } + /* Wait until a data is sent(not busy), before config /CS HIGH */ + while (SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET); + LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET); +} + +/** + * @brief Displays a full rectangle. + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @param Height: rectangle height. + * @param Width: rectangle width. + * @retval None + */ +void LCD_DrawFullRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height) +{ + LCD_SetTextColor(TextColor); + + LCD_DrawLine(Xpos, Ypos, Width, LCD_DIR_HORIZONTAL); + LCD_DrawLine((Xpos + Height), Ypos, Width, LCD_DIR_HORIZONTAL); + + LCD_DrawLine(Xpos, Ypos, Height, LCD_DIR_VERTICAL); + LCD_DrawLine(Xpos, (Ypos - Width + 1), Height, LCD_DIR_VERTICAL); + + Width -= 2; + Height--; + Ypos--; + + LCD_SetTextColor(BackColor); + + while(Height--) + { + LCD_DrawLine(++Xpos, Ypos, Width, LCD_DIR_HORIZONTAL); + } + + LCD_SetTextColor(TextColor); +} + +/** + * @brief Displays a full circle. + * @param Xpos: specifies the X position. + * @param Ypos: specifies the Y position. + * @param Radius + * @retval None + */ +void LCD_DrawFullCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius) +{ + int32_t D; /* Decision Variable */ + uint32_t CurX;/* Current X Value */ + uint32_t CurY;/* Current Y Value */ + + D = 3 - (Radius << 1); + + CurX = 0; + CurY = Radius; + + LCD_SetTextColor(BackColor); + + while (CurX <= CurY) + { + if(CurY > 0) + { + LCD_DrawLine(Xpos - CurX, Ypos + CurY, 2*CurY, LCD_DIR_HORIZONTAL); + LCD_DrawLine(Xpos + CurX, Ypos + CurY, 2*CurY, LCD_DIR_HORIZONTAL); + } + + if(CurX > 0) + { + LCD_DrawLine(Xpos - CurY, Ypos + CurX, 2*CurX, LCD_DIR_HORIZONTAL); + LCD_DrawLine(Xpos + CurY, Ypos + CurX, 2*CurX, LCD_DIR_HORIZONTAL); + } + if (D < 0) + { + D += (CurX << 2) + 6; + } + else + { + D += ((CurX - CurY) << 2) + 10; + CurY--; + } + CurX++; + } + + LCD_SetTextColor(TextColor); + LCD_DrawCircle(Xpos, Ypos, Radius); +} + +/** + * @brief Displays an uni line (between two points). + * @param x1: specifies the point 1 x position. + * @param y1: specifies the point 1 y position. + * @param x2: specifies the point 2 x position. + * @param y2: specifies the point 2 y position. + * @retval None + */ +void LCD_DrawUniLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) +{ + int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0, + yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0, + curpixel = 0; + + deltax = ABS(x2 - x1); /* The difference between the x's */ + deltay = ABS(y2 - y1); /* The difference between the y's */ + x = x1; /* Start x off at the first pixel */ + y = y1; /* Start y off at the first pixel */ + + if (x2 >= x1) /* The x-values are increasing */ + { + xinc1 = 1; + xinc2 = 1; + } + else /* The x-values are decreasing */ + { + xinc1 = -1; + xinc2 = -1; + } + + if (y2 >= y1) /* The y-values are increasing */ + { + yinc1 = 1; + yinc2 = 1; + } + else /* The y-values are decreasing */ + { + yinc1 = -1; + yinc2 = -1; + } + + if (deltax >= deltay) /* There is at least one x-value for every y-value */ + { + xinc1 = 0; /* Don't change the x when numerator >= denominator */ + yinc2 = 0; /* Don't change the y for every iteration */ + den = deltax; + num = deltax / 2; + numadd = deltay; + numpixels = deltax; /* There are more x-values than y-values */ + } + else /* There is at least one y-value for every x-value */ + { + xinc2 = 0; /* Don't change the x for every iteration */ + yinc1 = 0; /* Don't change the y when numerator >= denominator */ + den = deltay; + num = deltay / 2; + numadd = deltax; + numpixels = deltay; /* There are more y-values than x-values */ + } + + for (curpixel = 0; curpixel <= numpixels; curpixel++) + { + PutPixel(x, y); /* Draw the current pixel */ + num += numadd; /* Increase the numerator by the top of the fraction */ + if (num >= den) /* Check if numerator >= denominator */ + { + num -= den; /* Calculate the new numerator value */ + x += xinc1; /* Change the x as appropriate */ + y += yinc1; /* Change the y as appropriate */ + } + x += xinc2; /* Change the x as appropriate */ + y += yinc2; /* Change the y as appropriate */ + } +} + +/** + * @brief Displays an polyline (between many points). + * @param Points: pointer to the points array. + * @param PointCount: Number of points. + * @retval None + */ +void LCD_PolyLine(pPoint Points, uint16_t PointCount) +{ + int16_t X = 0, Y = 0; + + if(PointCount < 2) + { + return; + } + + while(--PointCount) + { + X = Points->X; + Y = Points->Y; + Points++; + LCD_DrawUniLine(X, Y, Points->X, Points->Y); + } +} + +/** + * @brief Displays an relative polyline (between many points). + * @param Points: pointer to the points array. + * @param PointCount: Number of points. + * @param Closed: specifies if the draw is closed or not. + * 1: closed, 0 : not closed. + * @retval None + */ +static void LCD_PolyLineRelativeClosed(pPoint Points, uint16_t PointCount, uint16_t Closed) +{ + int16_t X = 0, Y = 0; + pPoint First = Points; + + if(PointCount < 2) + { + return; + } + X = Points->X; + Y = Points->Y; + while(--PointCount) + { + Points++; + LCD_DrawUniLine(X, Y, X + Points->X, Y + Points->Y); + X = X + Points->X; + Y = Y + Points->Y; + } + if(Closed) + { + LCD_DrawUniLine(First->X, First->Y, X, Y); + } +} + +/** + * @brief Displays a closed polyline (between many points). + * @param Points: pointer to the points array. + * @param PointCount: Number of points. + * @retval None + */ +void LCD_ClosedPolyLine(pPoint Points, uint16_t PointCount) +{ + LCD_PolyLine(Points, PointCount); + LCD_DrawUniLine(Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y); +} + +/** + * @brief Displays a relative polyline (between many points). + * @param Points: pointer to the points array. + * @param PointCount: Number of points. + * @retval None + */ +void LCD_PolyLineRelative(pPoint Points, uint16_t PointCount) +{ + LCD_PolyLineRelativeClosed(Points, PointCount, 0); +} + +/** + * @brief Displays a closed relative polyline (between many points). + * @param Points: pointer to the points array. + * @param PointCount: Number of points. + * @retval None + */ +void LCD_ClosedPolyLineRelative(pPoint Points, uint16_t PointCount) +{ + LCD_PolyLineRelativeClosed(Points, PointCount, 1); +} + + +/** + * @brief Displays a full polyline (between many points). + * @param Points: pointer to the points array. + * @param PointCount: Number of points. + * @retval None + */ +void LCD_FillPolyLine(pPoint Points, uint16_t PointCount) +{ + /* public-domain code by Darel Rex Finley, 2007 */ + uint16_t nodes = 0, nodeX[MAX_POLY_CORNERS], pixelX = 0, pixelY = 0, i = 0, + j = 0, swap = 0; + uint16_t IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0; + + IMAGE_LEFT = IMAGE_RIGHT = Points->X; + IMAGE_TOP= IMAGE_BOTTOM = Points->Y; + + for(i = 1; i < PointCount; i++) + { + pixelX = POLY_X(i); + if(pixelX < IMAGE_LEFT) + { + IMAGE_LEFT = pixelX; + } + if(pixelX > IMAGE_RIGHT) + { + IMAGE_RIGHT = pixelX; + } + + pixelY = POLY_Y(i); + if(pixelY < IMAGE_TOP) + { + IMAGE_TOP = pixelY; + } + if(pixelY > IMAGE_BOTTOM) + { + IMAGE_BOTTOM = pixelY; + } + } + + LCD_SetTextColor(BackColor); + + /* Loop through the rows of the image. */ + for (pixelY = IMAGE_TOP; pixelY < IMAGE_BOTTOM; pixelY++) + { + /* Build a list of nodes. */ + nodes = 0; j = PointCount-1; + + for (i = 0; i < PointCount; i++) + { + if (((POLY_Y(i)<(double) pixelY) && (POLY_Y(j)>=(double) pixelY)) || ((POLY_Y(j)<(double) pixelY) && (POLY_Y(i)>=(double) pixelY))) + { + nodeX[nodes++]=(int) (POLY_X(i)+((pixelY-POLY_Y(i))*(POLY_X(j)-POLY_X(i)))/(POLY_Y(j)-POLY_Y(i))); + } + j = i; + } + + /* Sort the nodes, via a simple "Bubble" sort. */ + i = 0; + while (i < nodes-1) + { + if (nodeX[i]>nodeX[i+1]) + { + swap = nodeX[i]; + nodeX[i] = nodeX[i+1]; + nodeX[i+1] = swap; + if(i) + { + i--; + } + } + else + { + i++; + } + } + + /* Fill the pixels between node pairs. */ + for (i = 0; i < nodes; i+=2) + { + if(nodeX[i] >= IMAGE_RIGHT) + { + break; + } + if(nodeX[i+1] > IMAGE_LEFT) + { + if (nodeX[i] < IMAGE_LEFT) + { + nodeX[i]=IMAGE_LEFT; + } + if(nodeX[i+1] > IMAGE_RIGHT) + { + nodeX[i+1] = IMAGE_RIGHT; + } + LCD_SetTextColor(BackColor); + LCD_DrawLine(pixelY, nodeX[i+1], nodeX[i+1] - nodeX[i], LCD_DIR_HORIZONTAL); + LCD_SetTextColor(TextColor); + PutPixel(pixelY, nodeX[i+1]); + PutPixel(pixelY, nodeX[i]); + /* for (j=nodeX[i]; j<nodeX[i+1]; j++) PutPixel(j,pixelY); */ + } + } + } + + /* draw the edges */ + LCD_SetTextColor(TextColor); +} + +/** + * @brief Reset LCD control line(/CS) and Send Start-Byte + * @param Start_Byte: the Start-Byte to be sent + * @retval None + */ +void LCD_nCS_StartByte(uint8_t Start_Byte) +{ + LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_RESET); + + SPI_SendData8(LCD_SPI, Start_Byte); + + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET) + { + } +} + + +/** + * @brief Writes index to select the LCD register. + * @param LCD_Reg: address of the selected register. + * @retval None + */ +void LCD_WriteRegIndex(uint8_t LCD_Reg) +{ + /* Reset LCD control line(/CS) and Send Start-Byte */ + LCD_nCS_StartByte(START_BYTE | SET_INDEX); + + /* Write 16-bit Reg Index (High Byte is 0) */ + SPI_SendData8(LCD_SPI, 0x00); + + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET) + { + } + + SPI_SendData8(LCD_SPI, LCD_Reg); + + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET) + { + } + + LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET); +} + +/** + * @brief Reads the selected LCD Register. + * @param LCD_Reg: address of the selected register. + * @retval LCD Register Value. + */ +uint16_t LCD_ReadReg(uint8_t LCD_Reg) +{ + uint16_t tmp = 0; + uint8_t i = 0; + + /* LCD_SPI prescaler: 4 */ + LCD_SPI->CR1 &= 0xFFC7; + LCD_SPI->CR1 |= 0x0008; + + /* Check if the LCD controller is already recognized or not */ + if(LCDType == LCD_HX8347D) + { + /********************* HX8347D Read Sequence ******************************/ + /* Write 16-bit Index (then Read Reg) */ + LCD_WriteRegIndex(LCD_Reg); + + /* Read 16-bit Reg */ + /* Reset LCD control line(/CS) and Send Start-Byte */ + LCD_nCS_StartByte(START_BYTE | LCD_READ_REG); + + /* Wait until a data is sent(not busy), before reading dummy bytes*/ + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET) + + /* Read upper byte */ + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_TXE) == RESET); + SPI_SendData8(LCD_SPI, 0xFF); + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_RXNE)== RESET); + return(SPI_ReceiveData8(LCD_SPI)); + } + else + { + /* Write 16-bit Index (then Read Reg) */ + LCD_WriteRegIndex(LCD_Reg); + /* Read 16-bit Reg */ + /* Reset LCD control line(/CS) and Send Start-Byte */ + LCD_nCS_StartByte(START_BYTE | LCD_READ_REG); + + for(i = 0; i < 5; i++) + { + SPI_SendData8(LCD_SPI, 0xFF); + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET) + { + } + /* One byte of invalid dummy data read after the start byte */ + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_RXNE) == RESET) + { + } + SPI_ReceiveData8(LCD_SPI); + } + + SPI_SendData8(LCD_SPI, 0xFF); + + /* Read upper byte */ + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET) + { + } + + /* Read lower byte */ + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_RXNE) == RESET) + { + } + + SPI_SendData8(LCD_SPI, 0xFF); + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET) + { + } + + /* Read lower byte */ + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_RXNE) == RESET) + { + } + + tmp = SPI_I2S_ReceiveData16(LCD_SPI); + LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET); + + /* LCD_SPI prescaler: 2 */ + LCD_SPI->CR1 &= 0xFFC7; + } + return tmp; +} + + +/** + * @brief Prepare to write to the LCD RAM. + * @param None + * @retval None + */ +void LCD_WriteRAM_Prepare(void) +{ + LCD_WriteRegIndex(LCD_REG_34); /* Select GRAM Reg */ + + /* Reset LCD control line(/CS) and Send Start-Byte */ + LCD_nCS_StartByte(START_BYTE | LCD_WRITE_REG); +} + + +/** + * @brief Writes 1 word to the LCD RAM. + * @param RGB_Code: the pixel color in RGB mode (5-6-5). + * @retval None + */ +void LCD_WriteRAMWord(uint16_t RGB_Code) +{ + LCD_WriteRAM_Prepare(); + + LCD_WriteRAM(RGB_Code); + + LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET); +} + +/** + * @brief Writes to the selected LCD register. + * @param LCD_Reg: address of the selected register. + * @param LCD_RegValue: value to write to the selected register. + * @retval None + */ +void LCD_WriteReg(uint8_t LCD_Reg, uint16_t LCD_RegValue) +{ + /* Write 16-bit Index (then Write Reg) */ + LCD_WriteRegIndex(LCD_Reg); + + /* Write 16-bit Reg */ + /* Reset LCD control line(/CS) and Send Start-Byte */ + LCD_nCS_StartByte(START_BYTE | LCD_WRITE_REG); + + SPI_SendData8(LCD_SPI, LCD_RegValue>>8); + + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET) + { + } + + SPI_SendData8(LCD_SPI, (LCD_RegValue & 0xFF)); + + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET) + { + } + + LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET); +} + + +/** + * @brief Writes to the LCD RAM. + * @param RGB_Code: the pixel color in RGB mode (5-6-5). + * @retval None + */ +void LCD_WriteRAM(uint16_t RGB_Code) +{ + SPI_SendData8(LCD_SPI, RGB_Code >> 8); + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET) + { + } + + SPI_SendData8(LCD_SPI, RGB_Code & 0xFF); + while(SPI_I2S_GetFlagStatus(LCD_SPI, SPI_I2S_FLAG_BSY) != RESET) + { + } +} + +/** + * @brief Power on the LCD. + * @param None + * @retval None + */ +void LCD_PowerOn(void) +{ + if(LCDType == LCD_HX8347D) + { + /* Power on setting up flow */ + LCD_WriteReg(LCD_REG_24, 0x36); /* Display frame rate = 70Hz RADJ = '0110' */ + LCD_WriteReg(LCD_REG_25, 0x01); /* OSC_EN = 1 */ + LCD_WriteReg(LCD_REG_28, 0x06); /* AP[2:0] = 111 */ + LCD_WriteReg(LCD_REG_31,0x90); /* GAS=1, VOMG=00, PON=1, DK=0, XDK=0, DVDH_TRI=0, STB=0*/ + _delay_(10); + /* 262k/65k color selection */ + LCD_WriteReg(LCD_REG_23, 0x05); /* default 0x06 262k color, 0x05 65k color */ + /* SET PANEL */ + LCD_WriteReg(LCD_REG_54, 0x09); /* SS_PANEL = 1, GS_PANEL = 0,REV_PANEL = 0, BGR_PANEL = 1 */ + } + else + { + /* Power On sequence -----------------------------------------------------*/ + LCD_WriteReg(LCD_REG_16, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ + LCD_WriteReg(LCD_REG_17, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */ + LCD_WriteReg(LCD_REG_18, 0x0000); /* VREG1OUT voltage */ + LCD_WriteReg(LCD_REG_19, 0x0000); /* VDV[4:0] for VCOM amplitude */ + _delay_(20); /* Dis-charge capacitor power voltage (200ms) */ + LCD_WriteReg(LCD_REG_16, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */ + LCD_WriteReg(LCD_REG_17, 0x0137); /* DC1[2:0], DC0[2:0], VC[2:0] */ + _delay_(5); /* Delay 50 ms */ + LCD_WriteReg(LCD_REG_18, 0x0139); /* VREG1OUT voltage */ + _delay_(5); /* delay 50 ms */ + LCD_WriteReg(LCD_REG_19, 0x1d00); /* VDV[4:0] for VCOM amplitude */ + LCD_WriteReg(LCD_REG_41, 0x0013); /* VCM[4:0] for VCOMH */ + _delay_(5); /* delay 50 ms */ + LCD_WriteReg(LCD_REG_7, 0x0173); /* 262K color and display ON */ + } +} + + +/** + * @brief Enables the Display. + * @param None + * @retval None + */ +void LCD_DisplayOn(void) +{ + /* Display On */ + if(LCDType == LCD_HX8347D) + { + LCD_WriteReg(LCD_REG_40, 0x38); + _delay_(60); + LCD_WriteReg(LCD_REG_40, 0x3C); + } + else + { + LCD_WriteReg(LCD_REG_7, 0x0173); + } +} + + +/** + * @brief Disables the Display. + * @param None + * @retval None + */ +void LCD_DisplayOff(void) +{ + /* Display On */ + if(LCDType == LCD_HX8347D) + { + LCD_WriteReg(LCD_REG_40, 0x38); + _delay_(60); + LCD_WriteReg(LCD_REG_40, 0x04); + } + else + { + /* Display Off */ + LCD_WriteReg(LCD_REG_7, 0x0); + } +} + + +/** + * @brief Configures LCD control lines in Output Push-Pull mode. + * @param None + * @retval None + */ +void LCD_CtrlLinesConfig(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHBPeriphClockCmd(LCD_NCS_GPIO_CLK, ENABLE); + + /* Configure NCS in Output Push-Pull mode */ + GPIO_InitStructure.GPIO_Pin = LCD_NCS_PIN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(LCD_NCS_GPIO_PORT, &GPIO_InitStructure); + + LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET); +} + + +/** + * @brief Sets or reset LCD control lines. + * @param GPIOx: where x can be B or D to select the GPIO peripheral. + * @param CtrlPins: the Control line. + * This parameter can be: + * @arg LCD_NCS_PIN: Chip Select pin + * @arg LCD_NWR_PIN: Read/Write Selection pin + * @arg LCD_RS_PIN: Register/RAM Selection pin + * @param BitVal: specifies the value to be written to the selected bit. + * This parameter can be: + * @arg Bit_RESET: to clear the port pin + * @arg Bit_SET: to set the port pin + * @retval None + */ +void LCD_CtrlLinesWrite(GPIO_TypeDef* GPIOx, uint16_t CtrlPins, BitAction BitVal) +{ + /* Set or Reset the control line */ + GPIO_WriteBit(GPIOx, CtrlPins, BitVal); +} + + +/** + * @brief Configures the LCD_SPI interface. + * @param None + * @retval None + */ +void LCD_SPIConfig(void) +{ + SPI_InitTypeDef SPI_InitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + + /* Enable LCD_SPI_SCK_GPIO_CLK, LCD_SPI_MISO_GPIO_CLK and LCD_SPI_MOSI_GPIO_CLK clock */ + RCC_AHBPeriphClockCmd(LCD_SPI_SCK_GPIO_CLK | LCD_SPI_MISO_GPIO_CLK | LCD_SPI_MOSI_GPIO_CLK, ENABLE); + + /* Enable SYSCFG clock */ + RCC_APB2PeriphClockCmd(LCD_SPI_CLK | RCC_APB2Periph_SYSCFG, ENABLE); + + /* Enable LCD_SPI clock */ + RCC_APB1PeriphClockCmd(LCD_SPI_CLK, ENABLE); + + /* Configure LCD_SPI SCK pin */ + GPIO_InitStructure.GPIO_Pin = LCD_SPI_SCK_PIN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_Init(LCD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure); + + /* Configure LCD_SPI MISO pin */ + GPIO_InitStructure.GPIO_Pin = LCD_SPI_MISO_PIN; + GPIO_Init(LCD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure); + + /* Configure LCD_SPI MOSI pin */ + GPIO_InitStructure.GPIO_Pin = LCD_SPI_MOSI_PIN; + GPIO_Init(LCD_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure); + + /* Connect PE.13 to SPI SCK */ + GPIO_PinAFConfig(LCD_SPI_SCK_GPIO_PORT, LCD_SPI_SCK_SOURCE, LCD_SPI_SCK_AF); + + /* Connect PE.14 to SPI MISO */ + GPIO_PinAFConfig(LCD_SPI_MISO_GPIO_PORT, LCD_SPI_MISO_SOURCE, LCD_SPI_MISO_AF); + + /* Connect PE.15 to SPI MOSI */ + GPIO_PinAFConfig(LCD_SPI_MOSI_GPIO_PORT, LCD_SPI_MOSI_SOURCE, LCD_SPI_MOSI_AF); + + SPI_I2S_DeInit(LCD_SPI); + + /* SPI Config */ + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; + + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; + SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; + SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStructure.SPI_CRCPolynomial = 7; + SPI_Init(LCD_SPI, &SPI_InitStructure); + + /* Configure the RX FIFO Threshold to Quarter Full */ + SPI_RxFIFOThresholdConfig(LCD_SPI, SPI_RxFIFOThreshold_QF); + + /* SPI enable */ + SPI_Cmd(LCD_SPI, ENABLE); +} + +/** + * @brief Displays a pixel. + * @param x: pixel x. + * @param y: pixel y. + * @retval None + */ +static void PutPixel(int16_t x, int16_t y) +{ + if(x < 0 || x > 239 || y < 0 || y > 319) + { + return; + } + LCD_DrawLine(x, y, 1, LCD_DIR_HORIZONTAL); +} + +#ifndef USE_Delay +/** + * @brief Inserts a delay time. + * @param nCount: specifies the delay time length. + * @retval None + */ +static void delay(__IO uint32_t nCount) +{ + __IO uint32_t index = 0; + for(index = (34000 * nCount); index != 0; index--) + { + } +} +#endif /* USE_Delay*/ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_lcd.h b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_lcd.h new file mode 100644 index 0000000..31046a2 --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_lcd.h @@ -0,0 +1,428 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_lcd.h + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file contains all the functions prototypes for the stm32303c_eval_lcd + * firmware driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32303C_EVAL_LCD_H +#define __STM32303C_EVAL_LCD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32f30x.h" +#include "../Common/fonts.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL_LCD + * @{ + */ + + +/** @defgroup STM32303C_EVAL_LCD_Exported_Types + * @{ + */ +typedef struct +{ + int16_t X; + int16_t Y; +} Point, * pPoint; +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_LCD_Exported_Constants + * @{ + */ + +/** + * @brief Uncomment the line below if you want to use LCD_DrawBMP function to + * display a bitmap picture on the LCD. This function assumes that the bitmap + * file is loaded in the SPI Flash (mounted on STM32303C-EVAL board), however + * user can tailor it according to his application hardware requirement. + */ +/*#define USE_LCD_DrawBMP*/ + +/** + * @brief Uncomment the line below if you want to use user defined Delay function + * (for precise timing), otherwise default _delay_ function defined within + * this driver is used (less precise timing). + */ +/* #define USE_Delay */ + +#ifdef USE_Delay +#include "main.h" + + #define _delay_ Delay /* !< User can provide more timing precise _delay_ function + (with 10ms time base), using SysTick for example */ +#else + #define _delay_ delay /* !< Default _delay_ function with less precise timing */ +#endif + +/** + * @brief LCD Control Id + */ +#define LCD_ILI9320 0x9320 +#define LCD_SPFD5408 0x5408 +#define LCD_HX8347D 0x0047 + +/** + * @brief LCD Control pins + */ +#define LCD_NCS_PIN GPIO_Pin_0 +#define LCD_NCS_GPIO_PORT GPIOE +#define LCD_NCS_GPIO_CLK RCC_AHBPeriph_GPIOE + +/** + * @brief LCD SPI Interface pins + */ +#define LCD_SPI_SCK_PIN GPIO_Pin_9 /* PA.05 */ +#define LCD_SPI_SCK_GPIO_PORT GPIOF /* GPIOA */ +#define LCD_SPI_SCK_GPIO_CLK RCC_AHBPeriph_GPIOF +#define LCD_SPI_SCK_SOURCE GPIO_PinSource9 +#define LCD_SPI_SCK_AF GPIO_AF_5 + +#define LCD_SPI_MISO_PIN GPIO_Pin_14 /* PB.04 */ +#define LCD_SPI_MISO_GPIO_PORT GPIOB /* GPIOB */ +#define LCD_SPI_MISO_GPIO_CLK RCC_AHBPeriph_GPIOB +#define LCD_SPI_MISO_SOURCE GPIO_PinSource14 +#define LCD_SPI_MISO_AF GPIO_AF_5 + +#define LCD_SPI_MOSI_PIN GPIO_Pin_15 /* PA.07 */ +#define LCD_SPI_MOSI_GPIO_PORT GPIOB /* GPIOA */ +#define LCD_SPI_MOSI_GPIO_CLK RCC_AHBPeriph_GPIOB +#define LCD_SPI_MOSI_SOURCE GPIO_PinSource15 +#define LCD_SPI_MOSI_AF GPIO_AF_5 + +#define LCD_SPI SPI2 +#define LCD_SPI_CLK RCC_APB1Periph_SPI2 + +/** + * @brief LCD Registers + */ +#define LCD_REG_0 0x00 +#define LCD_REG_1 0x01 +#define LCD_REG_2 0x02 +#define LCD_REG_3 0x03 +#define LCD_REG_4 0x04 +#define LCD_REG_5 0x05 +#define LCD_REG_6 0x06 +#define LCD_REG_7 0x07 +#define LCD_REG_8 0x08 +#define LCD_REG_9 0x09 +#define LCD_REG_10 0x0A +#define LCD_REG_12 0x0C +#define LCD_REG_13 0x0D +#define LCD_REG_14 0x0E +#define LCD_REG_15 0x0F +#define LCD_REG_16 0x10 +#define LCD_REG_17 0x11 +#define LCD_REG_18 0x12 +#define LCD_REG_19 0x13 +#define LCD_REG_20 0x14 +#define LCD_REG_21 0x15 +#define LCD_REG_22 0x16 +#define LCD_REG_23 0x17 +#define LCD_REG_24 0x18 +#define LCD_REG_25 0x19 +#define LCD_REG_26 0x1A +#define LCD_REG_27 0x1B +#define LCD_REG_28 0x1C +#define LCD_REG_29 0x1D +#define LCD_REG_30 0x1E +#define LCD_REG_31 0x1F +#define LCD_REG_32 0x20 +#define LCD_REG_33 0x21 +#define LCD_REG_34 0x22 +#define LCD_REG_35 0x23 +#define LCD_REG_36 0x24 +#define LCD_REG_37 0x25 +#define LCD_REG_39 0x27 +#define LCD_REG_40 0x28 +#define LCD_REG_41 0x29 +#define LCD_REG_43 0x2B +#define LCD_REG_45 0x2D +#define LCD_REG_48 0x30 +#define LCD_REG_49 0x31 +#define LCD_REG_50 0x32 +#define LCD_REG_51 0x33 +#define LCD_REG_52 0x34 +#define LCD_REG_53 0x35 +#define LCD_REG_54 0x36 +#define LCD_REG_55 0x37 +#define LCD_REG_56 0x38 +#define LCD_REG_57 0x39 +#define LCD_REG_59 0x3B +#define LCD_REG_60 0x3C +#define LCD_REG_61 0x3D +#define LCD_REG_62 0x3E +#define LCD_REG_63 0x3F +#define LCD_REG_64 0x40 +#define LCD_REG_65 0x41 +#define LCD_REG_66 0x42 +#define LCD_REG_67 0x43 +#define LCD_REG_68 0x44 +#define LCD_REG_69 0x45 +#define LCD_REG_70 0x46 +#define LCD_REG_71 0x47 +#define LCD_REG_72 0x48 +#define LCD_REG_73 0x49 +#define LCD_REG_74 0x4A +#define LCD_REG_75 0x4B +#define LCD_REG_76 0x4C +#define LCD_REG_77 0x4D +#define LCD_REG_78 0x4E +#define LCD_REG_79 0x4F +#define LCD_REG_80 0x50 +#define LCD_REG_81 0x51 +#define LCD_REG_82 0x52 +#define LCD_REG_83 0x53 +#define LCD_REG_84 0x54 +#define LCD_REG_85 0x55 +#define LCD_REG_86 0x56 +#define LCD_REG_87 0x57 +#define LCD_REG_88 0x58 +#define LCD_REG_89 0x59 +#define LCD_REG_90 0x5A +#define LCD_REG_91 0x5B +#define LCD_REG_92 0x5C +#define LCD_REG_93 0x5D +#define LCD_REG_96 0x60 +#define LCD_REG_97 0x61 +#define LCD_REG_106 0x6A +#define LCD_REG_118 0x76 +#define LCD_REG_128 0x80 +#define LCD_REG_129 0x81 +#define LCD_REG_130 0x82 +#define LCD_REG_131 0x83 +#define LCD_REG_132 0x84 +#define LCD_REG_133 0x85 +#define LCD_REG_134 0x86 +#define LCD_REG_135 0x87 +#define LCD_REG_136 0x88 +#define LCD_REG_137 0x89 +#define LCD_REG_139 0x8B +#define LCD_REG_140 0x8C +#define LCD_REG_141 0x8D +#define LCD_REG_143 0x8F +#define LCD_REG_144 0x90 +#define LCD_REG_145 0x91 +#define LCD_REG_146 0x92 +#define LCD_REG_147 0x93 +#define LCD_REG_148 0x94 +#define LCD_REG_149 0x95 +#define LCD_REG_150 0x96 +#define LCD_REG_151 0x97 +#define LCD_REG_152 0x98 +#define LCD_REG_153 0x99 +#define LCD_REG_154 0x9A +#define LCD_REG_157 0x9D +#define LCD_REG_192 0xC0 +#define LCD_REG_193 0xC1 +#define LCD_REG_227 0xE3 +#define LCD_REG_229 0xE5 +#define LCD_REG_231 0xE7 +#define LCD_REG_239 0xEF +#define LCD_REG_232 0xE8 +#define LCD_REG_233 0xE9 +#define LCD_REG_234 0xEA +#define LCD_REG_235 0xEB +#define LCD_REG_236 0xEC +#define LCD_REG_237 0xED +#define LCD_REG_241 0xF1 +#define LCD_REG_242 0xF2 + + +/** + * @brief LCD color + */ +#define LCD_COLOR_WHITE 0xFFFF +#define LCD_COLOR_BLACK 0x0000 +#define LCD_COLOR_GREY 0xF7DE +#define LCD_COLOR_BLUE 0x001F +#define LCD_COLOR_BLUE2 0x051F +#define LCD_COLOR_RED 0xF800 +#define LCD_COLOR_MAGENTA 0xF81F +#define LCD_COLOR_GREEN 0x07E0 +#define LCD_COLOR_CYAN 0x7FFF +#define LCD_COLOR_YELLOW 0xFFE0 + +/** + * @brief LCD Lines depending on the chosen fonts. + */ +#define LCD_LINE_0 LINE(0) +#define LCD_LINE_1 LINE(1) +#define LCD_LINE_2 LINE(2) +#define LCD_LINE_3 LINE(3) +#define LCD_LINE_4 LINE(4) +#define LCD_LINE_5 LINE(5) +#define LCD_LINE_6 LINE(6) +#define LCD_LINE_7 LINE(7) +#define LCD_LINE_8 LINE(8) +#define LCD_LINE_9 LINE(9) +#define LCD_LINE_10 LINE(10) +#define LCD_LINE_11 LINE(11) +#define LCD_LINE_12 LINE(12) +#define LCD_LINE_13 LINE(13) +#define LCD_LINE_14 LINE(14) +#define LCD_LINE_15 LINE(15) +#define LCD_LINE_16 LINE(16) +#define LCD_LINE_17 LINE(17) +#define LCD_LINE_18 LINE(18) +#define LCD_LINE_19 LINE(19) +#define LCD_LINE_20 LINE(20) +#define LCD_LINE_21 LINE(21) +#define LCD_LINE_22 LINE(22) +#define LCD_LINE_23 LINE(23) +#define LCD_LINE_24 LINE(24) +#define LCD_LINE_25 LINE(25) +#define LCD_LINE_26 LINE(26) +#define LCD_LINE_27 LINE(27) +#define LCD_LINE_28 LINE(28) +#define LCD_LINE_29 LINE(29) + + +/** + * @brief LCD default font + */ +#define LCD_DEFAULT_FONT Font16x24 + +/** + * @brief LCD Direction + */ +#define LCD_DIR_HORIZONTAL 0x0000 +#define LCD_DIR_VERTICAL 0x0001 + +/** + * @brief LCD Size (Width and Height) + */ +#define LCD_PIXEL_WIDTH 0x0140 +#define LCD_PIXEL_HEIGHT 0x00F0 + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_LCD_Exported_Macros + * @{ + */ +#define ASSEMBLE_RGB(R, G, B) ((((R)& 0xF8) << 8) | (((G) & 0xFC) << 3) | (((B) & 0xF8) >> 3)) + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_LCD_Exported_Functions + * @{ + */ +void LCD_DeInit(void); +void LCD_Setup(void); +void LCD_SwapDirection(FunctionalState NewState); +void STM32303C_LCD_Init(void); +void LCD_SetColors(__IO uint16_t _TextColor, __IO uint16_t _BackColor); +void LCD_GetColors(__IO uint16_t *_TextColor, __IO uint16_t *_BackColor); +void LCD_SetTextColor(__IO uint16_t Color); +void LCD_SetBackColor(__IO uint16_t Color); +void LCD_ClearLine(uint8_t Line); +void LCD_Clear(uint16_t Color); +void LCD_SetCursor(uint8_t Xpos, uint16_t Ypos); +void LCD_DrawChar(uint8_t Xpos, uint16_t Ypos, const uint16_t *c); +void LCD_DisplayChar(uint8_t Line, uint16_t Column, uint8_t Ascii); +void LCD_SetFont(sFONT *fonts); +sFONT *LCD_GetFont(void); +void LCD_DisplayStringLine(uint8_t Line, uint8_t *ptr); +void LCD_SetDisplayWindow(uint8_t Xpos, uint16_t Ypos, uint8_t Height, uint16_t Width); +void LCD_WindowModeDisable(void); +void LCD_DrawLine(uint8_t Xpos, uint16_t Ypos, uint16_t Length, uint8_t Direction); +void LCD_DrawRect(uint8_t Xpos, uint16_t Ypos, uint8_t Height, uint16_t Width); +void LCD_DrawCircle(uint8_t Xpos, uint16_t Ypos, uint16_t Radius); +void LCD_DrawMonoPict(const uint32_t *Pict); +void LCD_DrawBMP(uint32_t BmpAddress); +void LCD_DrawUniLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2); +void LCD_DrawFullRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height); +void LCD_DrawFullCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius); +void LCD_PolyLine(pPoint Points, uint16_t PointCount); +void LCD_PolyLineRelative(pPoint Points, uint16_t PointCount); +void LCD_ClosedPolyLine(pPoint Points, uint16_t PointCount); +void LCD_ClosedPolyLineRelative(pPoint Points, uint16_t PointCount); +void LCD_FillPolyLine(pPoint Points, uint16_t PointCount); +void LCD_nCS_StartByte(uint8_t Start_Byte); +void LCD_WriteRegIndex(uint8_t LCD_Reg); +void LCD_WriteReg(uint8_t LCD_Reg, uint16_t LCD_RegValue); +void LCD_WriteRAM_Prepare(void); +void LCD_WriteRAMWord(uint16_t RGB_Code); +uint16_t LCD_ReadReg(uint8_t LCD_Reg); +void LCD_WriteRAM(uint16_t RGB_Code); +void LCD_PowerOn(void); +void LCD_DisplayOn(void); +void LCD_DisplayOff(void); + + +void LCD_CtrlLinesConfig(void); +void LCD_CtrlLinesWrite(GPIO_TypeDef* GPIOx, uint16_t CtrlPins, BitAction BitVal); +void LCD_SPIConfig(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32303C_EVAL_LCD_H */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_ee.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_ee.c new file mode 100644 index 0000000..9204230 --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_ee.c @@ -0,0 +1,490 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_spi_ee.c + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file provides a set of functions needed to manage the SPI M95xxx + * EEPROM memory mounted on STM32303C-EVAL board (refer to stm32303c_eval.h + * to know about the boards supporting this memory). + * It implements a high level communication layer for read and write + * from/to this memory. The needed STM32F30x hardware resources (SPI and + * GPIO) are defined in stm32303c_eval.h file, and the initialization is + * performed in SPI_sEE_LowLevel_Init() function declared in stm32303c_eval.c + * file. + * You can easily tailor this driver to any other development board, + * by just adapting the defines for hardware resources and + * SPI_sEE_LowLevel_Init() function. + * + * +-----------------------------------------------------------+ + * | Pin assignment | + * +-----------------------------+---------------+-------------+ + * | STM32 SPI Pins | sEE | Pin | + * +-----------------------------+---------------+-------------+ + * | sEE_CS_PIN | ChipSelect | 1 (/S) | + * | sEE_MISO_PIN / MISO | DataOut | 2 (Q) | + * | sEE_WP_PIN | WriteProtect | 3 (/W) | + * | | GND | 4 (0 V) | + * | sEE_MOSI_PIN / MOSI | DataIn | 5 (D) | + * | sEE_SCK_PIN / SCLK | Clock | 6 (C) | + * | | Hold | 7 (/HOLD)| + * | | VCC | 8 (3.3 V)| + * +-----------------------------+---------------+-------------+ + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval_spi_ee.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL_SPI_EE + * @brief This file includes the M95xxx SPI EEPROM driver of STM32303C-EVAL boards. + * @{ + */ + + +/** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Types + * @{ + */ + +uint16_t sEE_DataNum; +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Variables + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Function_Prototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_SPI_EEPROM_Private_Functions + * @{ + */ + +/** + * @brief DeInitializes the peripherals used by the SPI EEPROM driver. + * @param None + * @retval None + */ +void sEE_DeInit(void) +{ + sEE_SPI_LowLevel_DeInit(); +} + +/** + * @brief Initializes the peripherals used by the SPI EEPROM driver. + * @param None + * @retval None + */ +void sEE_Init(void) +{ + sEE_SPI_LowLevel_Init(); + + /*!< Deselect the EEPROM: Chip Select high */ + sEE_CS_HIGH(); +} + +/** + * @brief Writes more than one byte to the EEPROM with a single WRITE cycle + * (Page WRITE sequence). + * @note The number of byte can't exceed the EEPROM page size. + * @param pBuffer: pointer to the buffer containing the data to be written + * to the EEPROM. + * @param WriteAddr: EEPROM's internal address to write to. + * @param NumByteToWrite: number of bytes to write to the EEPROM, must be equal + * or less than "sEE_PAGESIZE" value. + * @retval None + */ +uint32_t sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t* NumByteToWrite) +{ + /*!< Enable the write access to the EEPROM */ + sEE_WriteEnable(); + + /*!< Select the EEPROM: Chip Select low */ + sEE_CS_LOW(); + + /*!< Send "Write to Memory " instruction */ + sEE_SendByte(sEE_CMD_WRITE); + + /*!< Send WriteAddr high nibble address byte to write to */ + sEE_SendByte((WriteAddr & 0xFF0000) >> 16); + + /*!< Send WriteAddr medium nibble address byte to write to */ + sEE_SendByte((WriteAddr & 0xFF00) >> 8); + + /*!< Send WriteAddr low nibble address byte to write to */ + sEE_SendByte(WriteAddr & 0xFF); + + /*!< while there is data to be written on the EEPROM */ + while ((*NumByteToWrite)--) + { + /*!< Send the current byte */ + sEE_SendByte(*pBuffer); + /*!< Point on the next byte to be written */ + pBuffer++; + } + + /*!< Deselect the EEPROM: Chip Select high */ + sEE_CS_HIGH(); + + /*!< Wait the end of EEPROM writing */ + sEE_WaitEepromStandbyState(); + + /*!< Disable the write access to the EEROM */ + sEE_WriteDisable(); + + return 0; +} + +/** + * @brief Writes block of data to the EEPROM. In this function, the number of + * WRITE cycles are reduced, using Page WRITE sequence. + * @param pBuffer: pointer to the buffer containing the data to be written + * to the EEPROM. + * @param WriteAddr: EEPROM's internal address to write to. + * @param NumByteToWrite: number of bytes to write to the EEPROM. + * @retval None + */ +void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite) +{ + uint16_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0; + + Addr = WriteAddr % sEE_PAGESIZE; + count = sEE_PAGESIZE - Addr; + NumOfPage = NumByteToWrite / sEE_PAGESIZE; + NumOfSingle = NumByteToWrite % sEE_PAGESIZE; + + if (Addr == 0) /*!< WriteAddr is sEE_PAGESIZE aligned */ + { + if (NumOfPage == 0) /*!< NumByteToWrite < sEE_PAGESIZE */ + { + sEE_DataNum = NumByteToWrite; + sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); + } + else /*!< NumByteToWrite > sEE_PAGESIZE */ + { + while (NumOfPage--) + { + sEE_DataNum = sEE_PAGESIZE; + sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); + WriteAddr += sEE_PAGESIZE; + pBuffer += sEE_PAGESIZE; + } + + sEE_DataNum = NumOfSingle; + sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); + } + } + else /*!< WriteAddr is not sEE_PAGESIZE aligned */ + { + if (NumOfPage == 0) /*!< NumByteToWrite < sEE_PAGESIZE */ + { + if (NumOfSingle > count) /*!< (NumByteToWrite + WriteAddr) > sEE_PAGESIZE */ + { + temp = NumOfSingle - count; + sEE_DataNum = count; + sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); + WriteAddr += count; + pBuffer += count; + + sEE_DataNum = temp; + sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); + } + else + { + sEE_DataNum = NumByteToWrite; + sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); + } + } + else /*!< NumByteToWrite > sEE_PAGESIZE */ + { + NumByteToWrite -= count; + NumOfPage = NumByteToWrite / sEE_PAGESIZE; + NumOfSingle = NumByteToWrite % sEE_PAGESIZE; + + sEE_DataNum = count; + + sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); + WriteAddr += count; + pBuffer += count; + + while (NumOfPage--) + { + sEE_DataNum = sEE_PAGESIZE; + + sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); + WriteAddr += sEE_PAGESIZE; + pBuffer += sEE_PAGESIZE; + } + + if (NumOfSingle != 0) + { + sEE_DataNum = NumOfSingle; + + sEE_WritePage(pBuffer, WriteAddr, &sEE_DataNum); + } + } + } +} + +/** + * @brief Reads a block of data from the EEPROM. + * @param pBuffer: pointer to the buffer that receives the data read from the EEPROM. + * @param ReadAddr: EEPROM's internal address to read from. + * @param NumByteToRead: number of bytes to read from the EEPROM. + * @retval None + */ +uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead) +{ + /*!< Select the EEPROM: Chip Select low */ + sEE_CS_LOW(); + + /*!< Send "Write to Memory " instruction */ + sEE_SendByte(sEE_CMD_READ); + + /*!< Send WriteAddr high nibble address byte to write to */ + sEE_SendByte((ReadAddr & 0xFF0000) >> 16); + + /*!< Send WriteAddr medium nibble address byte to write to */ + sEE_SendByte((ReadAddr & 0xFF00) >> 8); + + /*!< Send WriteAddr low nibble address byte to write to */ + sEE_SendByte(ReadAddr & 0xFF); + + while ((*NumByteToRead)--) /*!< while there is data to be read */ + { + /*!< Read a byte from the EEPROM */ + *pBuffer = sEE_SendByte(sEE_DUMMY_BYTE); + /*!< Point to the next location where the byte read will be saved */ + pBuffer++; + } + + /*!< Deselect the EEPROM: Chip Select high */ + sEE_CS_HIGH(); + + return 0; +} + + +/** + * @brief Reads a byte from the SPI EEPROM. + * @note This function must be used only if the Start_Read_Sequence function + * has been previously called. + * @param None + * @retval Byte Read from the SPI EEPROM. + */ +uint8_t sEE_ReadByte(void) +{ + return (sEE_SendByte(sEE_DUMMY_BYTE)); +} + +/** + * @brief Sends a byte through the SPI interface and return the byte received + * from the SPI bus. + * @param byte: byte to send. + * @retval The value of the received byte. + */ +uint8_t sEE_SendByte(uint8_t byte) +{ + /*!< Loop while DR register in not empty */ + while (SPI_I2S_GetFlagStatus(sEE_SPI, SPI_I2S_FLAG_TXE) == RESET); + + /*!< Send byte through the SPI peripheral */ + SPI_SendData8(sEE_SPI, byte); + + /*!< Wait to receive a byte */ + while (SPI_I2S_GetFlagStatus(sEE_SPI, SPI_I2S_FLAG_RXNE) == RESET); + + /*!< Return the byte read from the SPI bus */ + return SPI_ReceiveData8(sEE_SPI); +} +/** + * @brief Enables the write access to the EEPROM. + * @param None + * @retval None + */ +void sEE_WriteEnable(void) +{ + /*!< Select the EEPROM: Chip Select low */ + sEE_CS_LOW(); + + /*!< Send "Write Enable" instruction */ + sEE_SendByte(sEE_CMD_WREN); + + /*!< Deselect the EEPROM: Chip Select high */ + sEE_CS_HIGH(); +} + +/** + * @brief Disables the write access to the EEPROM. + * @param None + * @retval None + */ +void sEE_WriteDisable(void) +{ + /*!< Select the EEPROM: Chip Select low */ + sEE_CS_LOW(); + + /*!< Send "Write Disable" instruction */ + sEE_SendByte(sEE_CMD_WRDI); + + /*!< Deselect the EEPROM: Chip Select high */ + sEE_CS_HIGH(); +} + +/** + * @brief Write new value in EEPROM Status Register. + * @param regval : new value of register + * @retval None + */ +void sEE_WriteStatusRegister(uint8_t regval) +{ + /*!< Select the EEPROM: Chip Select low */ + sEE_CS_LOW(); + + /*!< Enable the write access to the EEPROM */ + sEE_WriteEnable(); + + /*!< Send "Write Status Register" instruction */ + sEE_SendByte(sEE_CMD_WRSR); + + /*!< Write regval in status register */ + sEE_SendByte(regval); + + /*!< Deselect the EEPROM: Chip Select high */ + sEE_CS_HIGH(); +} + +/** + * @brief Read EEPROM Status Register. + * @param None + * @retval The value of the Status register. + */ +uint8_t sEE_ReadStatusRegister(void) +{ + uint8_t sEEstatus = 0; + + /*!< Select the EEPROM: Chip Select low */ + sEE_CS_LOW(); + + /*!< Send "Read Status Register" instruction */ + sEE_SendByte(sEE_CMD_RDSR); + + /*!< Send a dummy byte to generate the clock needed by the EEPROM + and put the value of the status register in EEPROM Status variable */ + sEEstatus = sEE_SendByte(sEE_DUMMY_BYTE); + + /*!< Deselect the EEPROM: Chip Select high */ + sEE_CS_HIGH(); + + return sEEstatus; +} + +/** + * @brief Polls the status of the Write In Progress (WIP) flag in the EEPROM's + * status register and loop until write operation has completed. + * @param None + * @retval None + */ +uint32_t sEE_WaitEepromStandbyState(void) +{ + uint8_t sEEstatus = 0; + + /*!< Select the EEPROM: Chip Select low */ + sEE_CS_LOW(); + + /*!< Send "Read Status Register" instruction */ + sEE_SendByte(sEE_CMD_RDSR); + + /*!< Loop as long as the memory is busy with a write cycle */ + do + { + /*!< Send a dummy byte to generate the clock needed by the EEPROM + and put the value of the status register in EEPROM Status variable */ + sEEstatus = sEE_SendByte(sEE_DUMMY_BYTE); + + } + while ((sEEstatus & sEE_WIP_FLAG) == SET); /* Write in progress */ + + /*!< Deselect the EEPROM: Chip Select high */ + sEE_CS_HIGH(); + + return 0; +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_ee.h b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_ee.h new file mode 100644 index 0000000..1b29b22 --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_ee.h @@ -0,0 +1,156 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_spi_ee.h + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file contains all the functions prototypes for the stm32303c_eval_spi_ee + * firmware driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32303C_EVAL_SPI_EE_H +#define __STM32303C_EVAL_SPI_EE_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL_SPI_EE + * @{ + */ + +/** @defgroup STM32303C_EVAL_SPI_EEPROM_Exported_Types + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_SPI_EEPROM_Exported_Constants + * @{ + */ +/** + * @brief M95 SPI EEPROM supported commands + */ +#define sEE_CMD_WREN 0x06 /*!< Write enable instruction */ +#define sEE_CMD_WRDI 0x04 /*!< Write disable instruction */ +#define sEE_CMD_RDSR 0x05 /*!< Read Status Register instruction */ +#define sEE_CMD_WRSR 0x01 /*!< Write Status Register instruction */ +#define sEE_CMD_WRITE 0x02 /*!< Write to Memory instruction */ +#define sEE_CMD_READ 0x03 /*!< Read from Memory instruction */ + +/** + * @brief M95M01 SPI EEPROM defines + */ +#define sEE_WIP_FLAG 0x01 /*!< Write In Progress (WIP) flag */ + +#define sEE_DUMMY_BYTE 0xA5 + +#define sEE_PAGESIZE 256 + + + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_SPI_EEPROM_Exported_Macros + * @{ + */ +/** + * @brief Select EEPROM: Chip Select pin low + */ +#define sEE_CS_LOW() GPIO_ResetBits(sEE_SPI_CS_GPIO_PORT, sEE_SPI_CS_PIN) +/** + * @brief Deselect EEPROM: Chip Select pin high + */ +#define sEE_CS_HIGH() GPIO_SetBits(sEE_SPI_CS_GPIO_PORT, sEE_SPI_CS_PIN) +/** + * @} + */ + + + +/** @defgroup STM32303C_EVAL_SPI_EEPROM_Exported_Functions + * @{ + */ +/** + * @brief High layer functions + */ +void sEE_DeInit(void); +void sEE_Init(void); +uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead); +void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite); +uint32_t sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t* NumByteToWrite); +uint32_t sEE_WaitEepromStandbyState(void); + +/** + * @brief Low layer functions + */ +uint8_t sEE_ReadByte(void); +uint8_t sEE_SendByte(uint8_t byte); +void sEE_WriteEnable(void); +void sEE_WriteDisable(void); +void sEE_WriteStatusRegister(uint8_t regval); +uint8_t sEE_ReadStatusRegister(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32303C_EVAL_SPI_EE_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_sd.c b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_sd.c new file mode 100644 index 0000000..0550898 --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_sd.c @@ -0,0 +1,908 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_spi_sd.c + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file provides a set of functions needed to manage the SPI SD + * Card memory mounted on STM32303C-EVAL board. + * It implements a high level communication layer for read and write + * from/to this memory. The needed STM32F30x hardware resources (SPI and + * GPIO) are defined in stm32303c_eval.h file, and the initialization is + * performed in SD_LowLevel_Init() function declared in stm32303c_eval.c + * file. + * You can easily tailor this driver to any other development board, + * by just adapting the defines for hardware resources and + * SD_LowLevel_Init() function. + * + * +-------------------------------------------------------+ + * | Pin assignment | + * +-------------------------+---------------+-------------+ + * | STM32F30x SPI Pins | SD | Pin | + * +-------------------------+---------------+-------------+ + * | SD_SPI_CS_PIN | ChipSelect | 1 | + * | SD_SPI_MOSI_PIN / MOSI | DataIn | 2 | + * | | GND | 3 (0 V) | + * | | VDD | 4 (3.3 V)| + * | SD_SPI_SCK_PIN / SCLK | Clock | 5 | + * | | GND | 6 (0 V) | + * | SD_SPI_MISO_PIN / MISO | DataOut | 7 | + * +-------------------------+---------------+-------------+ + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval_spi_sd.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL_SPI_SD + * @brief This file includes the SD card driver of STM32303C-EVAL boards. + * @{ + */ + +/** @defgroup STM32303C_EVAL_SPI_SD_Private_Types + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_SPI_SD_Private_Defines + * @{ + */ +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_SPI_SD_Private_Macros + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_SPI_SD_Private_Variables + * @{ + */ + +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_SPI_SD_Private_Function_Prototypes + * @{ + */ +/** + * @} + */ + + +/** @defgroup STM32303C_EVAL_SPI_SD_Private_Functions + * @{ + */ + +/** + * @brief DeInitializes the SD/SD communication. + * @param None + * @retval None + */ +void SD_DeInit(void) +{ + SD_LowLevel_DeInit(); +} + +/** + * @brief Initializes the SD/SD communication. + * @param None + * @retval The SD Response: + * - SD_RESPONSE_FAILURE: Sequence failed + * - SD_RESPONSE_NO_ERROR: Sequence succeed + */ +SD_Error SD_Init(void) +{ + uint32_t i = 0; + + /*!< Initialize SD_SPI */ + SD_LowLevel_Init(); + + /*!< SD chip select high */ + SD_CS_HIGH(); + + /*!< Send dummy byte 0xFF, 10 times with CS high */ + /*!< Rise CS and MOSI for 80 clocks cycles */ + for (i = 0; i <= 9; i++) + { + /*!< Send dummy byte 0xFF */ + SD_WriteByte(SD_DUMMY_BYTE); + } + + /*------------Put SD in SPI mode--------------*/ + /*!< SD initialized and set to SPI mode properly */ + return (SD_GoIdleState()); +} + +/** + * @brief Detect if SD card is correctly plugged in the memory slot. + * @param None + * @retval Return if SD is detected or not + */ +uint8_t SD_Detect(void) +{ + __IO uint8_t status = SD_PRESENT; + + /*!< Check GPIO to detect SD */ + if (GPIO_ReadInputData(SD_DETECT_GPIO_PORT) & SD_DETECT_PIN) + { + status = SD_NOT_PRESENT; + } + return status; +} + +/** + * @brief Returns information about specific card. + * @param cardinfo: pointer to a SD_CardInfo structure that contains all SD + * card information. + * @retval The SD Response: + * - SD_RESPONSE_FAILURE: Sequence failed + * - SD_RESPONSE_NO_ERROR: Sequence succeed + */ +SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo) +{ + SD_Error status = SD_RESPONSE_FAILURE; + + SD_GetCSDRegister(&(cardinfo->SD_csd)); + status = SD_GetCIDRegister(&(cardinfo->SD_cid)); + cardinfo->CardCapacity = (cardinfo->SD_csd.DeviceSize + 1) ; + cardinfo->CardCapacity *= (1 << (cardinfo->SD_csd.DeviceSizeMul + 2)); + cardinfo->CardBlockSize = 1 << (cardinfo->SD_csd.RdBlockLen); + cardinfo->CardCapacity *= cardinfo->CardBlockSize; + + /*!< Returns the reponse */ + return status; +} + +/** + * @brief Reads a block of data from the SD. + * @param pBuffer: pointer to the buffer that receives the data read from the + * SD. + * @param ReadAddr: SD's internal address to read from. + * @param BlockSize: the SD card Data block size. + * @retval The SD Response: + * - SD_RESPONSE_FAILURE: Sequence failed + * - SD_RESPONSE_NO_ERROR: Sequence succeed + */ +SD_Error SD_ReadBlock(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t BlockSize) +{ + uint32_t i = 0; + SD_Error rvalue = SD_RESPONSE_FAILURE; + + /*!< SD chip select low */ + SD_CS_LOW(); + + /*!< Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */ + SD_SendCmd(SD_CMD_READ_SINGLE_BLOCK, ReadAddr, 0xFF); + + /*!< Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */ + if (!SD_GetResponse(SD_RESPONSE_NO_ERROR)) + { + /*!< Now look for the data token to signify the start of the data */ + if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ)) + { + /*!< Read the SD block data : read NumByteToRead data */ + for (i = 0; i < BlockSize; i++) + { + /*!< Save the received data */ + *pBuffer = SD_ReadByte(); + + /*!< Point to the next location where the byte read will be saved */ + pBuffer++; + } + /*!< Get CRC bytes (not really needed by us, but required by SD) */ + SD_ReadByte(); + SD_ReadByte(); + /*!< Set response value to success */ + rvalue = SD_RESPONSE_NO_ERROR; + } + } + /*!< SD chip select high */ + SD_CS_HIGH(); + + /*!< Send dummy byte: 8 Clock pulses of delay */ + SD_WriteByte(SD_DUMMY_BYTE); + + /*!< Returns the reponse */ + return rvalue; +} + +/** + * @brief Reads multiple block of data from the SD. + * @param pBuffer: pointer to the buffer that receives the data read from the + * SD. + * @param ReadAddr: SD's internal address to read from. + * @param BlockSize: the SD card Data block size. + * @param NumberOfBlocks: number of blocks to be read. + * @retval The SD Response: + * - SD_RESPONSE_FAILURE: Sequence failed + * - SD_RESPONSE_NO_ERROR: Sequence succeed + */ +SD_Error SD_ReadMultiBlocks(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks) +{ + uint32_t i = 0, Offset = 0; + SD_Error rvalue = SD_RESPONSE_FAILURE; + + /*!< SD chip select low */ + SD_CS_LOW(); + /*!< Data transfer */ + while (NumberOfBlocks--) + { + /*!< Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */ + SD_SendCmd (SD_CMD_READ_SINGLE_BLOCK, ReadAddr + Offset, 0xFF); + /*!< Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */ + if (SD_GetResponse(SD_RESPONSE_NO_ERROR)) + { + return SD_RESPONSE_FAILURE; + } + /*!< Now look for the data token to signify the start of the data */ + if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ)) + { + /*!< Read the SD block data : read NumByteToRead data */ + for (i = 0; i < BlockSize; i++) + { + /*!< Read the pointed data */ + *pBuffer = SD_ReadByte(); + /*!< Point to the next location where the byte read will be saved */ + pBuffer++; + } + /*!< Set next read address*/ + Offset += 512; + /*!< get CRC bytes (not really needed by us, but required by SD) */ + SD_ReadByte(); + SD_ReadByte(); + /*!< Set response value to success */ + rvalue = SD_RESPONSE_NO_ERROR; + } + else + { + /*!< Set response value to failure */ + rvalue = SD_RESPONSE_FAILURE; + } + } + /*!< SD chip select high */ + SD_CS_HIGH(); + /*!< Send dummy byte: 8 Clock pulses of delay */ + SD_WriteByte(SD_DUMMY_BYTE); + /*!< Returns the reponse */ + return rvalue; +} + +/** + * @brief Writes a block on the SD + * @param pBuffer: pointer to the buffer containing the data to be written on + * the SD. + * @param WriteAddr: address to write on. + * @param BlockSize: the SD card Data block size. + * @retval The SD Response: + * - SD_RESPONSE_FAILURE: Sequence failed + * - SD_RESPONSE_NO_ERROR: Sequence succeed + */ +SD_Error SD_WriteBlock(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t BlockSize) +{ + uint32_t i = 0; + SD_Error rvalue = SD_RESPONSE_FAILURE; + + /*!< SD chip select low */ + SD_CS_LOW(); + + /*!< Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write multiple block */ + SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr, 0xFF); + + /*!< Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ + if (!SD_GetResponse(SD_RESPONSE_NO_ERROR)) + { + /*!< Send a dummy byte */ + SD_WriteByte(SD_DUMMY_BYTE); + + /*!< Send the data token to signify the start of the data */ + SD_WriteByte(0xFE); + + /*!< Write the block data to SD : write count data by block */ + for (i = 0; i < BlockSize; i++) + { + /*!< Send the pointed byte */ + SD_WriteByte(*pBuffer); + /*!< Point to the next location where the byte read will be saved */ + pBuffer++; + } + /*!< Put CRC bytes (not really needed by us, but required by SD) */ + SD_ReadByte(); + SD_ReadByte(); + /*!< Read data response */ + if (SD_GetDataResponse() == SD_DATA_OK) + { + rvalue = SD_RESPONSE_NO_ERROR; + } + } + /*!< SD chip select high */ + SD_CS_HIGH(); + /*!< Send dummy byte: 8 Clock pulses of delay */ + SD_WriteByte(SD_DUMMY_BYTE); + + /*!< Returns the reponse */ + return rvalue; +} + +/** + * @brief Writes many blocks on the SD + * @param pBuffer: pointer to the buffer containing the data to be written on + * the SD. + * @param WriteAddr: address to write on. + * @param BlockSize: the SD card Data block size. + * @param NumberOfBlocks: number of blocks to be written. + * @retval The SD Response: + * - SD_RESPONSE_FAILURE: Sequence failed + * - SD_RESPONSE_NO_ERROR: Sequence succeed + */ +SD_Error SD_WriteMultiBlocks(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks) +{ + uint32_t i = 0, Offset = 0; + SD_Error rvalue = SD_RESPONSE_FAILURE; + + /*!< SD chip select low */ + SD_CS_LOW(); + /*!< Data transfer */ + while (NumberOfBlocks--) + { + /*!< Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write blocks */ + SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr + Offset, 0xFF); + /*!< Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ + if (SD_GetResponse(SD_RESPONSE_NO_ERROR)) + { + return SD_RESPONSE_FAILURE; + } + /*!< Send dummy byte */ + SD_WriteByte(SD_DUMMY_BYTE); + /*!< Send the data token to signify the start of the data */ + SD_WriteByte(SD_START_DATA_SINGLE_BLOCK_WRITE); + /*!< Write the block data to SD : write count data by block */ + for (i = 0; i < BlockSize; i++) + { + /*!< Send the pointed byte */ + SD_WriteByte(*pBuffer); + /*!< Point to the next location where the byte read will be saved */ + pBuffer++; + } + /*!< Set next write address */ + Offset += 512; + /*!< Put CRC bytes (not really needed by us, but required by SD) */ + SD_ReadByte(); + SD_ReadByte(); + /*!< Read data response */ + if (SD_GetDataResponse() == SD_DATA_OK) + { + /*!< Set response value to success */ + rvalue = SD_RESPONSE_NO_ERROR; + } + else + { + /*!< Set response value to failure */ + rvalue = SD_RESPONSE_FAILURE; + } + } + /*!< SD chip select high */ + SD_CS_HIGH(); + /*!< Send dummy byte: 8 Clock pulses of delay */ + SD_WriteByte(SD_DUMMY_BYTE); + /*!< Returns the reponse */ + return rvalue; +} + +/** + * @brief Read the CSD card register. + * Reading the contents of the CSD register in SPI mode is a simple + * read-block transaction. + * @param SD_csd: pointer on an SCD register structure + * @retval The SD Response: + * - SD_RESPONSE_FAILURE: Sequence failed + * - SD_RESPONSE_NO_ERROR: Sequence succeed + */ +SD_Error SD_GetCSDRegister(SD_CSD* SD_csd) +{ + uint32_t i = 0; + SD_Error rvalue = SD_RESPONSE_FAILURE; + uint8_t CSD_Tab[16]; + + /*!< SD chip select low */ + SD_CS_LOW(); + /*!< Send CMD9 (CSD register) or CMD10(CSD register) */ + SD_SendCmd(SD_CMD_SEND_CSD, 0, 0xFF); + /*!< Wait for response in the R1 format (0x00 is no errors) */ + if (!SD_GetResponse(SD_RESPONSE_NO_ERROR)) + { + if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ)) + { + for (i = 0; i < 16; i++) + { + /*!< Store CSD register value on CSD_Tab */ + CSD_Tab[i] = SD_ReadByte(); + } + } + /*!< Get CRC bytes (not really needed by us, but required by SD) */ + SD_WriteByte(SD_DUMMY_BYTE); + SD_WriteByte(SD_DUMMY_BYTE); + /*!< Set response value to success */ + rvalue = SD_RESPONSE_NO_ERROR; + } + /*!< SD chip select high */ + SD_CS_HIGH(); + /*!< Send dummy byte: 8 Clock pulses of delay */ + SD_WriteByte(SD_DUMMY_BYTE); + + /*!< Byte 0 */ + SD_csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6; + SD_csd->SysSpecVersion = (CSD_Tab[0] & 0x3C) >> 2; + SD_csd->Reserved1 = CSD_Tab[0] & 0x03; + + /*!< Byte 1 */ + SD_csd->TAAC = CSD_Tab[1]; + + /*!< Byte 2 */ + SD_csd->NSAC = CSD_Tab[2]; + + /*!< Byte 3 */ + SD_csd->MaxBusClkFrec = CSD_Tab[3]; + + /*!< Byte 4 */ + SD_csd->CardComdClasses = CSD_Tab[4] << 4; + + /*!< Byte 5 */ + SD_csd->CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4; + SD_csd->RdBlockLen = CSD_Tab[5] & 0x0F; + + /*!< Byte 6 */ + SD_csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7; + SD_csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6; + SD_csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5; + SD_csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4; + SD_csd->Reserved2 = 0; /*!< Reserved */ + + SD_csd->DeviceSize = (CSD_Tab[6] & 0x03) << 10; + + /*!< Byte 7 */ + SD_csd->DeviceSize |= (CSD_Tab[7]) << 2; + + /*!< Byte 8 */ + SD_csd->DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6; + + SD_csd->MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3; + SD_csd->MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07); + + /*!< Byte 9 */ + SD_csd->MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5; + SD_csd->MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2; + SD_csd->DeviceSizeMul = (CSD_Tab[9] & 0x03) << 1; + /*!< Byte 10 */ + SD_csd->DeviceSizeMul |= (CSD_Tab[10] & 0x80) >> 7; + + SD_csd->EraseGrSize = (CSD_Tab[10] & 0x40) >> 6; + SD_csd->EraseGrMul = (CSD_Tab[10] & 0x3F) << 1; + + /*!< Byte 11 */ + SD_csd->EraseGrMul |= (CSD_Tab[11] & 0x80) >> 7; + SD_csd->WrProtectGrSize = (CSD_Tab[11] & 0x7F); + + /*!< Byte 12 */ + SD_csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7; + SD_csd->ManDeflECC = (CSD_Tab[12] & 0x60) >> 5; + SD_csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2; + SD_csd->MaxWrBlockLen = (CSD_Tab[12] & 0x03) << 2; + + /*!< Byte 13 */ + SD_csd->MaxWrBlockLen |= (CSD_Tab[13] & 0xC0) >> 6; + SD_csd->WriteBlockPaPartial = (CSD_Tab[13] & 0x20) >> 5; + SD_csd->Reserved3 = 0; + SD_csd->ContentProtectAppli = (CSD_Tab[13] & 0x01); + + /*!< Byte 14 */ + SD_csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7; + SD_csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6; + SD_csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5; + SD_csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4; + SD_csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2; + SD_csd->ECC = (CSD_Tab[14] & 0x03); + + /*!< Byte 15 */ + SD_csd->CSD_CRC = (CSD_Tab[15] & 0xFE) >> 1; + SD_csd->Reserved4 = 1; + + /*!< Return the reponse */ + return rvalue; +} + +/** + * @brief Read the CID card register. + * Reading the contents of the CID register in SPI mode is a simple + * read-block transaction. + * @param SD_cid: pointer on an CID register structure + * @retval The SD Response: + * - SD_RESPONSE_FAILURE: Sequence failed + * - SD_RESPONSE_NO_ERROR: Sequence succeed + */ +SD_Error SD_GetCIDRegister(SD_CID* SD_cid) +{ + uint32_t i = 0; + SD_Error rvalue = SD_RESPONSE_FAILURE; + uint8_t CID_Tab[16]; + + /*!< SD chip select low */ + SD_CS_LOW(); + + /*!< Send CMD10 (CID register) */ + SD_SendCmd(SD_CMD_SEND_CID, 0, 0xFF); + + /*!< Wait for response in the R1 format (0x00 is no errors) */ + if (!SD_GetResponse(SD_RESPONSE_NO_ERROR)) + { + if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ)) + { + /*!< Store CID register value on CID_Tab */ + for (i = 0; i < 16; i++) + { + CID_Tab[i] = SD_ReadByte(); + } + } + /*!< Get CRC bytes (not really needed by us, but required by SD) */ + SD_WriteByte(SD_DUMMY_BYTE); + SD_WriteByte(SD_DUMMY_BYTE); + /*!< Set response value to success */ + rvalue = SD_RESPONSE_NO_ERROR; + } + /*!< SD chip select high */ + SD_CS_HIGH(); + /*!< Send dummy byte: 8 Clock pulses of delay */ + SD_WriteByte(SD_DUMMY_BYTE); + + /*!< Byte 0 */ + SD_cid->ManufacturerID = CID_Tab[0]; + + /*!< Byte 1 */ + SD_cid->OEM_AppliID = CID_Tab[1] << 8; + + /*!< Byte 2 */ + SD_cid->OEM_AppliID |= CID_Tab[2]; + + /*!< Byte 3 */ + SD_cid->ProdName1 = CID_Tab[3] << 24; + + /*!< Byte 4 */ + SD_cid->ProdName1 |= CID_Tab[4] << 16; + + /*!< Byte 5 */ + SD_cid->ProdName1 |= CID_Tab[5] << 8; + + /*!< Byte 6 */ + SD_cid->ProdName1 |= CID_Tab[6]; + + /*!< Byte 7 */ + SD_cid->ProdName2 = CID_Tab[7]; + + /*!< Byte 8 */ + SD_cid->ProdRev = CID_Tab[8]; + + /*!< Byte 9 */ + SD_cid->ProdSN = CID_Tab[9] << 24; + + /*!< Byte 10 */ + SD_cid->ProdSN |= CID_Tab[10] << 16; + + /*!< Byte 11 */ + SD_cid->ProdSN |= CID_Tab[11] << 8; + + /*!< Byte 12 */ + SD_cid->ProdSN |= CID_Tab[12]; + + /*!< Byte 13 */ + SD_cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4; + SD_cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8; + + /*!< Byte 14 */ + SD_cid->ManufactDate |= CID_Tab[14]; + + /*!< Byte 15 */ + SD_cid->CID_CRC = (CID_Tab[15] & 0xFE) >> 1; + SD_cid->Reserved2 = 1; + + /*!< Return the reponse */ + return rvalue; +} + +/** + * @brief Send 5 bytes command to the SD card. + * @param Cmd: The user expected command to send to SD card. + * @param Arg: The command argument. + * @param Crc: The CRC. + * @retval None + */ +void SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc) +{ + uint32_t i = 0x00; + + uint8_t Frame[6]; + + Frame[0] = (Cmd | 0x40); /*!< Construct byte 1 */ + + Frame[1] = (uint8_t)(Arg >> 24); /*!< Construct byte 2 */ + + Frame[2] = (uint8_t)(Arg >> 16); /*!< Construct byte 3 */ + + Frame[3] = (uint8_t)(Arg >> 8); /*!< Construct byte 4 */ + + Frame[4] = (uint8_t)(Arg); /*!< Construct byte 5 */ + + Frame[5] = (Crc); /*!< Construct CRC: byte 6 */ + + for (i = 0; i < 6; i++) + { + SD_WriteByte(Frame[i]); /*!< Send the Cmd bytes */ + } +} + +/** + * @brief Get SD card data response. + * @param None + * @retval The SD status: Read data response xxx0<status>1 + * - status 010: Data accecpted + * - status 101: Data rejected due to a crc error + * - status 110: Data rejected due to a Write error. + * - status 111: Data rejected due to other error. + */ +uint8_t SD_GetDataResponse(void) +{ + uint32_t i = 0; + uint8_t response, rvalue; + + while (i <= 64) + { + /*!< Read resonse */ + response = SD_ReadByte(); + /*!< Mask unused bits */ + response &= 0x1F; + switch (response) + { + case SD_DATA_OK: + { + rvalue = SD_DATA_OK; + break; + } + case SD_DATA_CRC_ERROR: + return SD_DATA_CRC_ERROR; + case SD_DATA_WRITE_ERROR: + return SD_DATA_WRITE_ERROR; + default: + { + rvalue = SD_DATA_OTHER_ERROR; + break; + } + } + /*!< Exit loop in case of data ok */ + if (rvalue == SD_DATA_OK) + break; + /*!< Increment loop counter */ + i++; + } + + /*!< Wait null data */ + while (SD_ReadByte() == 0); + + /*!< Return response */ + return response; +} + +/** + * @brief Returns the SD response. + * @param None + * @retval The SD Response: + * - SD_RESPONSE_FAILURE: Sequence failed + * - SD_RESPONSE_NO_ERROR: Sequence succeed + */ +SD_Error SD_GetResponse(uint8_t Response) +{ + uint32_t Count = 0xFFF; + + /* Check if response is got or a timeout is happen */ + while ((SD_ReadByte() != Response) && Count) + { + Count--; + } + + if (Count == 0) + { + /* After time out */ + return SD_RESPONSE_FAILURE; + } + else + { + /* Right response got */ + return SD_RESPONSE_NO_ERROR; + } +} + +/** + * @brief Returns the SD status. + * @param None + * @retval The SD status. + */ +uint16_t SD_GetStatus(void) +{ + uint16_t Status = 0; + + /*!< SD chip select low */ + SD_CS_LOW(); + + /*!< Send CMD13 (SD_SEND_STATUS) to get SD status */ + SD_SendCmd(SD_CMD_SEND_STATUS, 0, 0xFF); + + Status = SD_ReadByte(); + Status |= (uint16_t)(SD_ReadByte() << 8); + + /*!< SD chip select high */ + SD_CS_HIGH(); + + /*!< Send dummy byte 0xFF */ + SD_WriteByte(SD_DUMMY_BYTE); + + return Status; +} + +/** + * @brief Put SD in Idle state. + * @param None + * @retval The SD Response: + * - SD_RESPONSE_FAILURE: Sequence failed + * - SD_RESPONSE_NO_ERROR: Sequence succeed + */ +SD_Error SD_GoIdleState(void) +{ + /*!< SD chip select low */ + SD_CS_LOW(); + + /*!< Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode */ + SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95); + + /*!< Wait for In Idle State Response (R1 Format) equal to 0x01 */ + if (SD_GetResponse(SD_IN_IDLE_STATE)) + { + /*!< No Idle State Response: return response failue */ + return SD_RESPONSE_FAILURE; + } + /*----------Activates the card initialization process-----------*/ + do + { + /*!< SD chip select high */ + SD_CS_HIGH(); + + /*!< Send Dummy byte 0xFF */ + SD_WriteByte(SD_DUMMY_BYTE); + + /*!< SD chip select low */ + SD_CS_LOW(); + + /*!< Send CMD1 (Activates the card process) until response equal to 0x0 */ + SD_SendCmd(SD_CMD_SEND_OP_COND, 0, 0xFF); + /*!< Wait for no error Response (R1 Format) equal to 0x00 */ + } + while (SD_GetResponse(SD_RESPONSE_NO_ERROR)); + + /*!< SD chip select high */ + SD_CS_HIGH(); + + /*!< Send dummy byte 0xFF */ + SD_WriteByte(SD_DUMMY_BYTE); + + return SD_RESPONSE_NO_ERROR; +} + +/** + * @brief Write a byte on the SD. + * @param Data: byte to send. + * @retval None + */ +uint8_t SD_WriteByte(uint8_t Data) +{ + /*!< Wait until the transmit buffer is empty */ + while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_TXE) == RESET) + { + } + + /*!< Send the byte */ + SPI_SendData8(SD_SPI, Data); + + /*!< Wait to receive a byte*/ + while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_RXNE) == RESET) + { + } + + /*!< Return the byte read from the SPI bus */ + return SPI_ReceiveData8(SD_SPI); +} + +/** + * @brief Read a byte from the SD. + * @param None + * @retval The received byte. + */ +uint8_t SD_ReadByte(void) +{ + uint8_t Data = 0; + + /*!< Wait until the transmit buffer is empty */ + while (SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_TXE) == RESET) + { + } + /*!< Send the byte */ + SPI_SendData8(SD_SPI, SD_DUMMY_BYTE); + + /*!< Wait until a data is received */ + while (SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_RXNE) == RESET) + { + } + /*!< Get the received data */ + Data = SPI_ReceiveData8(SD_SPI); + + /*!< Return the shifted data */ + return Data; +} + +/** + * @} + */ + + +/** + * @} + */ + + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_sd.h b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_sd.h new file mode 100644 index 0000000..28c0ccc --- /dev/null +++ b/thirdparty/STM32_USB-FS-Device_Lib_V4.0.0/Utilities/STM32_EVAL/STM32303C_EVAL/stm32303c_eval_spi_sd.h @@ -0,0 +1,286 @@ +/** + ****************************************************************************** + * @file stm32303c_eval_spi_sd.h + * @author MCD Application Team + * @version V1.0.1 + * @date 23-October-2012 + * @brief This file contains all the functions prototypes for the stm32303c_eval_spi_sd + * firmware driver. + ****************************************************************************** + * @attention + * + * <h2><center>© COPYRIGHT 2012 STMicroelectronics</center></h2> + * + * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); + * You may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.st.com/software_license_agreement_liberty_v2 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32303C_EVAL_SPI_SD_H +#define __STM32303C_EVAL_SPI_SD_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include "stm32303c_eval.h" + +/** @addtogroup Utilities + * @{ + */ + +/** @addtogroup STM32_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL + * @{ + */ + +/** @addtogroup STM32303C_EVAL_SPI_SD + * @{ + */ + +/** @defgroup STM32303C_EVAL_SPI_SD_Exported_Types + * @{ + */ + +typedef enum +{ +/** + * @brief SD reponses and error flags + */ + SD_RESPONSE_NO_ERROR = (0x00), + SD_IN_IDLE_STATE = (0x01), + SD_ERASE_RESET = (0x02), + SD_ILLEGAL_COMMAND = (0x04), + SD_COM_CRC_ERROR = (0x08), + SD_ERASE_SEQUENCE_ERROR = (0x10), + SD_ADDRESS_ERROR = (0x20), + SD_PARAMETER_ERROR = (0x40), + SD_RESPONSE_FAILURE = (0xFF), + +/** + * @brief Data response error + */ + SD_DATA_OK = (0x05), + SD_DATA_CRC_ERROR = (0x0B), + SD_DATA_WRITE_ERROR = (0x0D), + SD_DATA_OTHER_ERROR = (0xFF) +} SD_Error; + +/** + * @brief Card Specific Data: CSD Register + */ +typedef struct +{ + __IO uint8_t CSDStruct; /*!< CSD structure */ + __IO uint8_t SysSpecVersion; /*!< System specification version */ + __IO uint8_t Reserved1; /*!< Reserved */ + __IO uint8_t TAAC; /*!< Data read access-time 1 */ + __IO uint8_t NSAC; /*!< Data read access-time 2 in CLK cycles */ + __IO uint8_t MaxBusClkFrec; /*!< Max. bus clock frequency */ + __IO uint16_t CardComdClasses; /*!< Card command classes */ + __IO uint8_t RdBlockLen; /*!< Max. read data block length */ + __IO uint8_t PartBlockRead; /*!< Partial blocks for read allowed */ + __IO uint8_t WrBlockMisalign; /*!< Write block misalignment */ + __IO uint8_t RdBlockMisalign; /*!< Read block misalignment */ + __IO uint8_t DSRImpl; /*!< DSR implemented */ + __IO uint8_t Reserved2; /*!< Reserved */ + __IO uint32_t DeviceSize; /*!< Device Size */ + __IO uint8_t MaxRdCurrentVDDMin; /*!< Max. read current @ VDD min */ + __IO uint8_t MaxRdCurrentVDDMax; /*!< Max. read current @ VDD max */ + __IO uint8_t MaxWrCurrentVDDMin; /*!< Max. write current @ VDD min */ + __IO uint8_t MaxWrCurrentVDDMax; /*!< Max. write current @ VDD max */ + __IO uint8_t DeviceSizeMul; /*!< Device size multiplier */ + __IO uint8_t EraseGrSize; /*!< Erase group size */ + __IO uint8_t EraseGrMul; /*!< Erase group size multiplier */ + __IO uint8_t WrProtectGrSize; /*!< Write protect group size */ + __IO uint8_t WrProtectGrEnable; /*!< Write protect group enable */ + __IO uint8_t ManDeflECC; /*!< Manufacturer default ECC */ + __IO uint8_t WrSpeedFact; /*!< Write speed factor */ + __IO uint8_t MaxWrBlockLen; /*!< Max. write data block length */ + __IO uint8_t WriteBlockPaPartial; /*!< Partial blocks for write allowed */ + __IO uint8_t Reserved3; /*!< Reserded */ + __IO uint8_t ContentProtectAppli; /*!< Content protection application */ + __IO uint8_t FileFormatGrouop; /*!< File format group */ + __IO uint8_t CopyFlag; /*!< Copy flag (OTP) */ + __IO uint8_t PermWrProtect; /*!< Permanent write protection */ + __IO uint8_t TempWrProtect; /*!< Temporary write protection */ + __IO uint8_t FileFormat; /*!< File Format */ + __IO uint8_t ECC; /*!< ECC code */ + __IO uint8_t CSD_CRC; /*!< CSD CRC */ + __IO uint8_t Reserved4; /*!< always 1*/ +} SD_CSD; + +/** + * @brief Card Identification Data: CID Register + */ +typedef struct +{ + __IO uint8_t ManufacturerID; /*!< ManufacturerID */ + __IO uint16_t OEM_AppliID; /*!< OEM/Application ID */ + __IO uint32_t ProdName1; /*!< Product Name part1 */ + __IO uint8_t ProdName2; /*!< Product Name part2*/ + __IO uint8_t ProdRev; /*!< Product Revision */ + __IO uint32_t ProdSN; /*!< Product Serial Number */ + __IO uint8_t Reserved1; /*!< Reserved1 */ + __IO uint16_t ManufactDate; /*!< Manufacturing Date */ + __IO uint8_t CID_CRC; /*!< CID CRC */ + __IO uint8_t Reserved2; /*!< always 1 */ +} SD_CID; + +/** + * @brief SD Card information + */ +typedef struct +{ + SD_CSD SD_csd; + SD_CID SD_cid; + uint32_t CardCapacity; /*!< Card Capacity */ + uint32_t CardBlockSize; /*!< Card Block Size */ +} SD_CardInfo; + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_SPI_SD_Exported_Constants + * @{ + */ + +/** + * @brief Block Size + */ +#define SD_BLOCK_SIZE 0x200 + +/** + * @brief Dummy byte + */ +#define SD_DUMMY_BYTE 0xFF + +/** + * @brief Start Data tokens: + * Tokens (necessary because at nop/idle (and CS active) only 0xff is + * on the data/command line) + */ +#define SD_START_DATA_SINGLE_BLOCK_READ 0xFE /*!< Data token start byte, Start Single Block Read */ +#define SD_START_DATA_MULTIPLE_BLOCK_READ 0xFE /*!< Data token start byte, Start Multiple Block Read */ +#define SD_START_DATA_SINGLE_BLOCK_WRITE 0xFE /*!< Data token start byte, Start Single Block Write */ +#define SD_START_DATA_MULTIPLE_BLOCK_WRITE 0xFD /*!< Data token start byte, Start Multiple Block Write */ +#define SD_STOP_DATA_MULTIPLE_BLOCK_WRITE 0xFD /*!< Data toke stop byte, Stop Multiple Block Write */ + +/** + * @brief SD detection on its memory slot + */ +#define SD_PRESENT ((uint8_t)0x01) +#define SD_NOT_PRESENT ((uint8_t)0x00) + + +/** + * @brief Commands: CMDxx = CMD-number | 0x40 + */ +#define SD_CMD_GO_IDLE_STATE 0 /*!< CMD0 = 0x40 */ +#define SD_CMD_SEND_OP_COND 1 /*!< CMD1 = 0x41 */ +#define SD_CMD_SEND_CSD 9 /*!< CMD9 = 0x49 */ +#define SD_CMD_SEND_CID 10 /*!< CMD10 = 0x4A */ +#define SD_CMD_STOP_TRANSMISSION 12 /*!< CMD12 = 0x4C */ +#define SD_CMD_SEND_STATUS 13 /*!< CMD13 = 0x4D */ +#define SD_CMD_SET_BLOCKLEN 16 /*!< CMD16 = 0x50 */ +#define SD_CMD_READ_SINGLE_BLOCK 17 /*!< CMD17 = 0x51 */ +#define SD_CMD_READ_MULT_BLOCK 18 /*!< CMD18 = 0x52 */ +#define SD_CMD_SET_BLOCK_COUNT 23 /*!< CMD23 = 0x57 */ +#define SD_CMD_WRITE_SINGLE_BLOCK 24 /*!< CMD24 = 0x58 */ +#define SD_CMD_WRITE_MULT_BLOCK 25 /*!< CMD25 = 0x59 */ +#define SD_CMD_PROG_CSD 27 /*!< CMD27 = 0x5B */ +#define SD_CMD_SET_WRITE_PROT 28 /*!< CMD28 = 0x5C */ +#define SD_CMD_CLR_WRITE_PROT 29 /*!< CMD29 = 0x5D */ +#define SD_CMD_SEND_WRITE_PROT 30 /*!< CMD30 = 0x5E */ +#define SD_CMD_SD_ERASE_GRP_START 32 /*!< CMD32 = 0x60 */ +#define SD_CMD_SD_ERASE_GRP_END 33 /*!< CMD33 = 0x61 */ +#define SD_CMD_UNTAG_SECTOR 34 /*!< CMD34 = 0x62 */ +#define SD_CMD_ERASE_GRP_START 35 /*!< CMD35 = 0x63 */ +#define SD_CMD_ERASE_GRP_END 36 /*!< CMD36 = 0x64 */ +#define SD_CMD_UNTAG_ERASE_GROUP 37 /*!< CMD37 = 0x65 */ +#define SD_CMD_ERASE 38 /*!< CMD38 = 0x66 */ + +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_SPI_SD_Exported_Macros + * @{ + */ +/** + * @brief Select SD Card: ChipSelect pin low + */ +#define SD_CS_LOW() GPIO_ResetBits(SD_CS_GPIO_PORT, SD_CS_PIN) +/** + * @brief Deselect SD Card: ChipSelect pin high + */ +#define SD_CS_HIGH() GPIO_SetBits(SD_CS_GPIO_PORT, SD_CS_PIN) +/** + * @} + */ + +/** @defgroup STM32303C_EVAL_SPI_SD_Exported_Functions + * @{ + */ +void SD_DeInit(void); +SD_Error SD_Init(void); +uint8_t SD_Detect(void); +SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo); +SD_Error SD_ReadBlock(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t BlockSize); +SD_Error SD_ReadMultiBlocks(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks); +SD_Error SD_WriteBlock(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t BlockSize); +SD_Error SD_WriteMultiBlocks(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks); +SD_Error SD_GetCSDRegister(SD_CSD* SD_csd); +SD_Error SD_GetCIDRegister(SD_CID* SD_cid); + +void SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc); +SD_Error SD_GetResponse(uint8_t Response); +uint8_t SD_GetDataResponse(void); +SD_Error SD_GoIdleState(void); +uint16_t SD_GetStatus(void); + +uint8_t SD_WriteByte(uint8_t byte); +uint8_t SD_ReadByte(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32303C_EVAL_SPI_SD_H */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |