├── .github ├── ISSUE_TEMPLATE.md └── PULL_REQUEST_TEMPLATE.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── Release_Notes.html ├── SECURITY.md ├── _htmresc ├── Add button.svg ├── Update.svg ├── favicon.png ├── mini-st_2020.css ├── st_logo.png └── st_logo_2020.png ├── ov5640.c ├── ov5640.h ├── ov5640_reg.c └── ov5640_reg.h /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: 'Bug report' 3 | about: 'Create a report to help us improve the quality of our software' 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Caution** 10 | 11 | The Issues are strictly limited for the reporting of problem encountered with the software provided in this project. 12 | For any other problem related to the STM32 product, the performance, the hardware characteristics and boards, the tools the environment in general, please post your report to the **ST Community** in the STM32 MCUs dedicated [page](https://community.st.com/s/group/0F90X000000AXsASAW/stm32-mcus). 13 | 14 | **Describe the set-up** 15 | 16 | * The board (either ST RPN reference or your custom board) 17 | * IDE or at least the compiler and its version 18 | 19 | **Describe the bug (skip if none)** 20 | 21 | A clear and concise description of what the bug is. 22 | 23 | **How to reproduce the bug (skip if none)** 24 | 25 | 1. Indicate the global behavior of your application project 26 | 2. List the modules that you suspect to be the cause of the problem (Drivers, BSP, MW...) 27 | 3. Describe the use case that generates the problem 28 | 4. How we can reproduce the problem 29 | 30 | 31 | **Additional context** 32 | 33 | If you have a first analysis, an enhancement, a fix or a patch, thank you to share your proposal. 34 | 35 | **Screenshots** 36 | 37 | If applicable, add screenshots to help explain your problem. 38 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## IMPORTANT INFORMATION 2 | 3 | Pull-requests are **not** accepted on this repository. Please use issues to report any bug or request. 4 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team via this [link](https://www.st.com/content/st_com/en/contact-us.html). 59 | All complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 1.4, 71 | available [here](https://www.contributor-covenant.org/version/1/4/code-of-conduct.html). 72 | 73 | For answers to common questions about this code of conduct, see the [FAQ section](https://www.contributor-covenant.org/faq). 74 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing guide 2 | 3 | This document serves as a checklist before contributing to this repository. 4 | It includes links to read up on if topics are unclear to you. 5 | 6 | This guide mainly focuses on steps to be followed to submit an issue or a pull-request. 7 | 8 | ### 1. Before opening an issue 9 | 10 | To report a bug or a request please file an issue in the right repository 11 | (example for [ov5640](https://github.com/STMicroelectronics/ov5640/issues/new/choose)). 12 | 13 | Please check the following boxes before posting an issue: 14 | - [ ] `Make sure you are using the latest commit (major releases are tagged, but corrections are available as new commits).` 15 | - [ ] `Make sure your issue is a question/feedback/suggestions RELATED TO the software provided in this repository.` Otherwise, it should be submitted to the ST Community under the MCU topic [page](https://community.st.com/s/group/0F90X000000AXsASAW/stm32-mcus). 16 | - [ ] `Make sure your issue is not already reported/fixed on GitHub or discussed on a previous issue.` Please refer to this [dashboard](https://github.com/orgs/STMicroelectronics/projects/2) for the list of issues and pull-requests. Do not forget to browse into the **closed** issues. 17 | 18 | ### 2. Posting the issue 19 | When you have checked the previous boxes. You will find two templates (Bug Report or Other Issue) available in the **Issues** tab of the repository. 20 | 21 | ### 3. Pull Requests 22 | Pull-requests are **not** accepted on this repository. Please use **issues** to report any bug or request. 23 | 24 | ### 4. How to proceed 25 | 26 | * We recommend to engage first a communication thru an issue, in order to present your proposal. Just to confirm that it corresponds to STMicroelectronics domain or scope. 27 | * Then fork the project to your GitHub account to further develop your contribution. Please use the latest commit version. 28 | * Please, submit one Pull Request for one new feature or proposal. This will ease the analysis and the final merge if accepted. 29 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2019(-2020) STMicroelectronics. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors 15 | may be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BSP OV5640 Component 2 | 3 | ## Overview 4 | 5 | **STM32Cube** is an STMicroelectronics original initiative to ease the developers life by reducing efforts, time and cost. 6 | 7 | **STM32Cube** covers the overall STM32 products portfolio. It includes a comprehensive embedded software platform delivered for each STM32 series. 8 | * The CMSIS modules (core and device) corresponding to the ARM(tm) core implemented in this STM32 product. 9 | * The STM32 HAL-LL drivers, an abstraction layer offering a set of APIs ensuring maximized portability across the STM32 portfolio. 10 | * The BSP drivers of each evaluation, demonstration or nucleo board provided for this STM32 series. 11 | * A consistent set of middleware components such as RTOS, USB, FatFS, graphics, touch sensing library... 12 | * A full set of software projects (basic examples, applications, and demonstrations) for each board provided for this STM32 series. 13 | 14 | Two models of publication are proposed for the STM32Cube embedded software: 15 | * The monolithic **MCU Package**: all STM32Cube software modules of one STM32 series are present (Drivers, Middleware, Projects, Utilities) in the repository (usual name **STM32Cubexx**, xx corresponding to the STM32 series). 16 | * The **MCU component**: each STM32Cube software module being part of the STM32Cube MCU Package, is delivered as an individual repository, allowing the user to select and get only the required software functions. 17 | 18 | ## Description 19 | 20 | This **ov5640** MCU component repository is one element **common to all** STM32Cube MCU embedded software packages, providing the **OV5640** BSP CAMERA component part. 21 | 22 | ## License 23 | 24 | Copyright (c) 2019 STMicroelectronics 25 | 26 | This software component is licensed by STMicroelectronics under the **BSD-3-Clause** license. You may not use this software except in compliance with this license. You may obtain a copy of the license [here](https://opensource.org/licenses/BSD-3-Clause). 27 | 28 | ## Release note 29 | 30 | Details about the content of this release are available in the release note [here](https://htmlpreview.github.io/?https://github.com/STMicroelectronics/ov5640/blob/main/Release_Notes.html). 31 | 32 | ## Compatibility information 33 | 34 | Please refer to the repository of the BSP **board** driver you are using to know which version of this BSP component driver to use. It is **crucial** that you use a consistent set of versions. It is **crucial** that you use a consistent set of versions as indicated. 35 | 36 | ## Troubleshooting 37 | 38 | If you have any issue with the **software content** of this repository, you can file an issue [here](https://github.com/STMicroelectronics/ov5640/issues/new/choose). 39 | 40 | For any other question related to the product, the tools, the environment, you can submit a topic to the [ST Community](https://community.st.com/s/). 41 | -------------------------------------------------------------------------------- /Release_Notes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Release Notes for OV5640 Component Driver 8 | 14 | 15 | 18 | 19 | 20 | 21 |
22 |
23 |
24 |

Release Notes for

25 |

OV5640 Component Driver

26 |

Copyright © 2019-2024 STMicroelectronics
27 |

28 | 29 |
30 |

Purpose

31 |

This driver provides a set of camera functions offered by OV5640 component

32 |
33 |
34 |

Update History

35 |
36 | 37 |
38 |

Main Changes

39 |
    40 |
  • Update Timing for 800x480 resolution
  • 41 |
  • Add 48 MHz Pixel clock support
  • 42 |
  • Correct return value for parallel mode config
  • 43 |
44 |
45 |
46 |
47 | 48 |
49 |

Main Changes

50 |
    51 |
  • Correct pclk clock setting at 9 and 12 MHz in OV5640_SetPCLK() function.
  • 52 |
53 |
54 |
55 |
56 | 57 |
58 |

Main Changes

59 |
    60 |
  • Add support of serial interface: 61 |
      62 |
    • OV5640_Init() must be called for either PARALLEL_MODE or SERIAL_MODE.
    • 63 |
  • 64 |
65 |

Backward compatibility

66 |
    67 |
  • This software breaks the compatibility with previous versions
  • 68 |
69 |
70 |
71 |
72 | 73 |
74 |

Main Changes

75 |
    76 |
  • Update license
  • 77 |
78 |
79 |
80 |
81 | 82 |
83 |

Main Changes

84 |
    85 |
  • Code Spell fixed
  • 86 |
87 |
88 |
89 |
90 | 91 |
92 |

Main Changes

93 |
    94 |
  • Update license
  • 95 |
96 |
97 |
98 |
99 | 100 |
101 |

Main Changes

102 |
    103 |
  • Formatting update
  • 104 |
105 |
106 |
107 |
108 | 109 |
110 |

Main Changes

111 |
    112 |
  • Set default Pixel clock to 12Mhz
  • 113 |
  • Add OV5640_SetPixelClock() API
  • 114 |
  • Set HTS and VTS timings to get 7.5fps when using default PCLK=12MHz
  • 115 |
  • Check Misra-C 2012 coding rules compliance
  • 116 |
  • Formatting update
  • 117 |
118 |
119 |
120 |
121 | 122 |
123 |

Main Changes

124 |
    125 |
  • Add support of RGB888, YUV422, Y8 and JPEG formats
  • 126 |
  • Add support gradual vertical colorbar
  • 127 |
  • Codespell miss-spelling errors correction.
  • 128 |
129 |
130 |
131 |
132 | 133 |
134 |

Main Changes

135 |
    136 |
  • Second Official Release of OV5640 Camera Component drivers in line with legacy BSP drivers development guidelines
  • 137 |
  • Add Support of the following features: 138 |
      139 |
    • OV5640 SetPolarities
    • 140 |
    • OV5640 GetPolarities
    • 141 |
    • OV5640 ColorBar handling
    • 142 |
    • OV5640 Embedded Synchronization mode
    • 143 |
  • 144 |
145 |

Dependencies

146 |

This software release is compatible with:

147 |
    148 |
  • BSP Common version v6.0.0 or above
  • 149 |
150 |

Backward compatibility

151 |
    152 |
  • This software breaks the compatibility with previous version v2.0.0
  • 153 |
  • This software is compatible with version v1.0.0
  • 154 |
155 |
156 |
157 |
158 | 159 |
160 |

Main Changes

161 |
    162 |
  • Official Release of OV5640 Camera Component drivers in line with legacy BSP drivers development guidelines
    163 |
  • 164 |
  • The component drivers are composed of 165 |
      166 |
    • component core drivers files: ov5640.h/.c
    • 167 |
  • 168 |
169 |

Dependencies

170 |

This software release is compatible with:

171 |
    172 |
  • BSP Common version v5.1.2 or lower versions
  • 173 |
174 |

Backward compatibility

175 |
    176 |
  • This software breaks the compatibility with previous version v1.0.0
  • 177 |
178 |
179 |
180 |
181 | 182 |
183 |

Main Changes

184 |
    185 |
  • First Official Release of OV5640 Camera Component drivers in line with STM32Cube BSP drivers development guidelines (UM2298)
    186 |
  • 187 |
  • The component drivers are composed of 188 |
      189 |
    • component core drivers files: ov5640.h/.c
    • 190 |
    • component register drivers files: ov5640_regs.h/.c
    • 191 |
  • 192 |
193 |

Dependencies

194 |

This software release is compatible with:

195 |
    196 |
  • BSP Common v6.0.0 or above
  • 197 |
198 |
199 |
200 |
201 |
202 | 205 | 206 | 207 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Report potential product security vulnerabilities 2 | 3 | ST places a high priority on security, and our Product Security Incident 4 | Response Team (PSIRT) is committed to rapidly addressing potential security 5 | vulnerabilities affecting our products. PSIRT's long history and vast experience 6 | in security allows ST to perform clear analyses and provide appropriate guidance 7 | on mitigations and solutions when applicable. 8 | 9 | If you wish to report potential security vulnerabilities regarding our products, 10 | **please do not report them through public GitHub issues.** Instead, we 11 | encourage you to report them to our ST PSIRT following the process described at: 12 | **https://www.st.com/content/st_com/en/security/report-vulnerabilities.html** 13 | 14 | ### IMPORTANT - READ CAREFULLY: 15 | 16 | STMicroelectronics International N.V., on behalf of itself, its affiliates and 17 | subsidiaries, (collectively “ST”) takes all potential security vulnerability 18 | reports or other related communications (“Report(s)”) seriously. In order to 19 | review Your Report (the terms “You” and “Yours” include your employer, and all 20 | affiliates, subsidiaries and related persons or entities) and take actions as 21 | deemed appropriate, ST requires that we have the rights and Your permission to 22 | do so. 23 | 24 | As such, by submitting Your Report to ST, You agree that You have the right to 25 | do so, and You grant to ST the rights to use the Report for purposes related to 26 | security vulnerability analysis, testing, correction, patching, reporting and 27 | any other related purpose or function. 28 | 29 | By submitting Your Report, You agree that ST’s 30 | [Privacy Policy](https://www.st.com/content/st_com/en/common/privacy-portal.html) 31 | applies to all related communications. 32 | -------------------------------------------------------------------------------- /_htmresc/Add button.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_htmresc/Update.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /_htmresc/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STMicroelectronics/stm32-ov5640/d0c3aef81cd17b3a32907a341377d2a44d95d82b/_htmresc/favicon.png -------------------------------------------------------------------------------- /_htmresc/mini-st_2020.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* 3 | Flavor name: Custom (mini-custom) 4 | Generated online - https://minicss.org/flavors 5 | mini.css version: v3.0.1 6 | */ 7 | /* 8 | Browsers resets and base typography. 9 | */ 10 | /* Core module CSS variable definitions */ 11 | :root { 12 | --fore-color: #03234b; 13 | --secondary-fore-color: #03234b; 14 | --back-color: #ffffff; 15 | --secondary-back-color: #ffffff; 16 | --blockquote-color: #e6007e; 17 | --pre-color: #e6007e; 18 | --border-color: #3cb4e6; 19 | --secondary-border-color: #3cb4e6; 20 | --heading-ratio: 1.2; 21 | --universal-margin: 0.5rem; 22 | --universal-padding: 0.25rem; 23 | --universal-border-radius: 0.075rem; 24 | --background-margin: 1.5%; 25 | --a-link-color: #3cb4e6; 26 | --a-visited-color: #8c0078; } 27 | 28 | html { 29 | font-size: 13.5px; } 30 | 31 | a, b, del, em, i, ins, q, span, strong, u { 32 | font-size: 1em; } 33 | 34 | html, * { 35 | font-family: -apple-system, BlinkMacSystemFont, Helvetica, arial, sans-serif; 36 | line-height: 1.25; 37 | -webkit-text-size-adjust: 100%; } 38 | 39 | * { 40 | font-size: 1rem; } 41 | 42 | body { 43 | margin: 0; 44 | color: var(--fore-color); 45 | @background: var(--back-color); 46 | background: var(--back-color) linear-gradient(#ffd200, #ffd200) repeat-y left top; 47 | background-size: var(--background-margin); 48 | } 49 | 50 | details { 51 | display: block; } 52 | 53 | summary { 54 | display: list-item; } 55 | 56 | abbr[title] { 57 | border-bottom: none; 58 | text-decoration: underline dotted; } 59 | 60 | input { 61 | overflow: visible; } 62 | 63 | img { 64 | max-width: 100%; 65 | height: auto; } 66 | 67 | h1, h2, h3, h4, h5, h6 { 68 | line-height: 1.25; 69 | margin: calc(1.5 * var(--universal-margin)) var(--universal-margin); 70 | font-weight: 400; } 71 | h1 small, h2 small, h3 small, h4 small, h5 small, h6 small { 72 | color: var(--secondary-fore-color); 73 | display: block; 74 | margin-top: -0.25rem; } 75 | 76 | h1 { 77 | font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) * var(--heading-ratio)); } 78 | 79 | h2 { 80 | font-size: calc(1rem * var(--heading-ratio) * var(--heading-ratio) ); 81 | border-style: none none solid none ; 82 | border-width: thin; 83 | border-color: var(--border-color); } 84 | h3 { 85 | font-size: calc(1rem * var(--heading-ratio) ); } 86 | 87 | h4 { 88 | font-size: calc(1rem * var(--heading-ratio)); } 89 | 90 | h5 { 91 | font-size: 1rem; } 92 | 93 | h6 { 94 | font-size: calc(1rem / var(--heading-ratio)); } 95 | 96 | p { 97 | margin: var(--universal-margin); } 98 | 99 | ol, ul { 100 | margin: var(--universal-margin); 101 | padding-left: calc(3 * var(--universal-margin)); } 102 | 103 | b, strong { 104 | font-weight: 700; } 105 | 106 | hr { 107 | box-sizing: content-box; 108 | border: 0; 109 | line-height: 1.25em; 110 | margin: var(--universal-margin); 111 | height: 0.0714285714rem; 112 | background: linear-gradient(to right, transparent, var(--border-color) 20%, var(--border-color) 80%, transparent); } 113 | 114 | blockquote { 115 | display: block; 116 | position: relative; 117 | font-style: italic; 118 | color: var(--secondary-fore-color); 119 | margin: var(--universal-margin); 120 | padding: calc(3 * var(--universal-padding)); 121 | border: 0.0714285714rem solid var(--secondary-border-color); 122 | border-left: 0.3rem solid var(--blockquote-color); 123 | border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } 124 | blockquote:before { 125 | position: absolute; 126 | top: calc(0rem - var(--universal-padding)); 127 | left: 0; 128 | font-family: sans-serif; 129 | font-size: 2rem; 130 | font-weight: 800; 131 | content: "\201c"; 132 | color: var(--blockquote-color); } 133 | blockquote[cite]:after { 134 | font-style: normal; 135 | font-size: 0.75em; 136 | font-weight: 700; 137 | content: "\a— " attr(cite); 138 | white-space: pre; } 139 | 140 | code, kbd, pre, samp { 141 | font-family: Menlo, Consolas, monospace; 142 | font-size: 0.85em; } 143 | 144 | code { 145 | background: var(--secondary-back-color); 146 | border-radius: var(--universal-border-radius); 147 | padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } 148 | 149 | kbd { 150 | background: var(--fore-color); 151 | color: var(--back-color); 152 | border-radius: var(--universal-border-radius); 153 | padding: calc(var(--universal-padding) / 4) calc(var(--universal-padding) / 2); } 154 | 155 | pre { 156 | overflow: auto; 157 | background: var(--secondary-back-color); 158 | padding: calc(1.5 * var(--universal-padding)); 159 | margin: var(--universal-margin); 160 | border: 0.0714285714rem solid var(--secondary-border-color); 161 | border-left: 0.2857142857rem solid var(--pre-color); 162 | border-radius: 0 var(--universal-border-radius) var(--universal-border-radius) 0; } 163 | 164 | sup, sub, code, kbd { 165 | line-height: 0; 166 | position: relative; 167 | vertical-align: baseline; } 168 | 169 | small, sup, sub, figcaption { 170 | font-size: 0.75em; } 171 | 172 | sup { 173 | top: -0.5em; } 174 | 175 | sub { 176 | bottom: -0.25em; } 177 | 178 | figure { 179 | margin: var(--universal-margin); } 180 | 181 | figcaption { 182 | color: var(--secondary-fore-color); } 183 | 184 | a { 185 | text-decoration: none; } 186 | a:link { 187 | color: var(--a-link-color); } 188 | a:visited { 189 | color: var(--a-visited-color); } 190 | a:hover, a:focus { 191 | text-decoration: underline; } 192 | 193 | /* 194 | Definitions for the grid system, cards and containers. 195 | */ 196 | .container { 197 | margin: 0 auto; 198 | padding: 0 calc(1.5 * var(--universal-padding)); } 199 | 200 | .row { 201 | box-sizing: border-box; 202 | display: flex; 203 | flex: 0 1 auto; 204 | flex-flow: row wrap; 205 | margin: 0 0 0 var(--background-margin); } 206 | 207 | .col-sm, 208 | [class^='col-sm-'], 209 | [class^='col-sm-offset-'], 210 | .row[class*='cols-sm-'] > * { 211 | box-sizing: border-box; 212 | flex: 0 0 auto; 213 | padding: 0 calc(var(--universal-padding) / 2); } 214 | 215 | .col-sm, 216 | .row.cols-sm > * { 217 | max-width: 100%; 218 | flex-grow: 1; 219 | flex-basis: 0; } 220 | 221 | .col-sm-1, 222 | .row.cols-sm-1 > * { 223 | max-width: 8.3333333333%; 224 | flex-basis: 8.3333333333%; } 225 | 226 | .col-sm-offset-0 { 227 | margin-left: 0; } 228 | 229 | .col-sm-2, 230 | .row.cols-sm-2 > * { 231 | max-width: 16.6666666667%; 232 | flex-basis: 16.6666666667%; } 233 | 234 | .col-sm-offset-1 { 235 | margin-left: 8.3333333333%; } 236 | 237 | .col-sm-3, 238 | .row.cols-sm-3 > * { 239 | max-width: 25%; 240 | flex-basis: 25%; } 241 | 242 | .col-sm-offset-2 { 243 | margin-left: 16.6666666667%; } 244 | 245 | .col-sm-4, 246 | .row.cols-sm-4 > * { 247 | max-width: 33.3333333333%; 248 | flex-basis: 33.3333333333%; } 249 | 250 | .col-sm-offset-3 { 251 | margin-left: 25%; } 252 | 253 | .col-sm-5, 254 | .row.cols-sm-5 > * { 255 | max-width: 41.6666666667%; 256 | flex-basis: 41.6666666667%; } 257 | 258 | .col-sm-offset-4 { 259 | margin-left: 33.3333333333%; } 260 | 261 | .col-sm-6, 262 | .row.cols-sm-6 > * { 263 | max-width: 50%; 264 | flex-basis: 50%; } 265 | 266 | .col-sm-offset-5 { 267 | margin-left: 41.6666666667%; } 268 | 269 | .col-sm-7, 270 | .row.cols-sm-7 > * { 271 | max-width: 58.3333333333%; 272 | flex-basis: 58.3333333333%; } 273 | 274 | .col-sm-offset-6 { 275 | margin-left: 50%; } 276 | 277 | .col-sm-8, 278 | .row.cols-sm-8 > * { 279 | max-width: 66.6666666667%; 280 | flex-basis: 66.6666666667%; } 281 | 282 | .col-sm-offset-7 { 283 | margin-left: 58.3333333333%; } 284 | 285 | .col-sm-9, 286 | .row.cols-sm-9 > * { 287 | max-width: 75%; 288 | flex-basis: 75%; } 289 | 290 | .col-sm-offset-8 { 291 | margin-left: 66.6666666667%; } 292 | 293 | .col-sm-10, 294 | .row.cols-sm-10 > * { 295 | max-width: 83.3333333333%; 296 | flex-basis: 83.3333333333%; } 297 | 298 | .col-sm-offset-9 { 299 | margin-left: 75%; } 300 | 301 | .col-sm-11, 302 | .row.cols-sm-11 > * { 303 | max-width: 91.6666666667%; 304 | flex-basis: 91.6666666667%; } 305 | 306 | .col-sm-offset-10 { 307 | margin-left: 83.3333333333%; } 308 | 309 | .col-sm-12, 310 | .row.cols-sm-12 > * { 311 | max-width: 100%; 312 | flex-basis: 100%; } 313 | 314 | .col-sm-offset-11 { 315 | margin-left: 91.6666666667%; } 316 | 317 | .col-sm-normal { 318 | order: initial; } 319 | 320 | .col-sm-first { 321 | order: -999; } 322 | 323 | .col-sm-last { 324 | order: 999; } 325 | 326 | @media screen and (min-width: 500px) { 327 | .col-md, 328 | [class^='col-md-'], 329 | [class^='col-md-offset-'], 330 | .row[class*='cols-md-'] > * { 331 | box-sizing: border-box; 332 | flex: 0 0 auto; 333 | padding: 0 calc(var(--universal-padding) / 2); } 334 | 335 | .col-md, 336 | .row.cols-md > * { 337 | max-width: 100%; 338 | flex-grow: 1; 339 | flex-basis: 0; } 340 | 341 | .col-md-1, 342 | .row.cols-md-1 > * { 343 | max-width: 8.3333333333%; 344 | flex-basis: 8.3333333333%; } 345 | 346 | .col-md-offset-0 { 347 | margin-left: 0; } 348 | 349 | .col-md-2, 350 | .row.cols-md-2 > * { 351 | max-width: 16.6666666667%; 352 | flex-basis: 16.6666666667%; } 353 | 354 | .col-md-offset-1 { 355 | margin-left: 8.3333333333%; } 356 | 357 | .col-md-3, 358 | .row.cols-md-3 > * { 359 | max-width: 25%; 360 | flex-basis: 25%; } 361 | 362 | .col-md-offset-2 { 363 | margin-left: 16.6666666667%; } 364 | 365 | .col-md-4, 366 | .row.cols-md-4 > * { 367 | max-width: 33.3333333333%; 368 | flex-basis: 33.3333333333%; } 369 | 370 | .col-md-offset-3 { 371 | margin-left: 25%; } 372 | 373 | .col-md-5, 374 | .row.cols-md-5 > * { 375 | max-width: 41.6666666667%; 376 | flex-basis: 41.6666666667%; } 377 | 378 | .col-md-offset-4 { 379 | margin-left: 33.3333333333%; } 380 | 381 | .col-md-6, 382 | .row.cols-md-6 > * { 383 | max-width: 50%; 384 | flex-basis: 50%; } 385 | 386 | .col-md-offset-5 { 387 | margin-left: 41.6666666667%; } 388 | 389 | .col-md-7, 390 | .row.cols-md-7 > * { 391 | max-width: 58.3333333333%; 392 | flex-basis: 58.3333333333%; } 393 | 394 | .col-md-offset-6 { 395 | margin-left: 50%; } 396 | 397 | .col-md-8, 398 | .row.cols-md-8 > * { 399 | max-width: 66.6666666667%; 400 | flex-basis: 66.6666666667%; } 401 | 402 | .col-md-offset-7 { 403 | margin-left: 58.3333333333%; } 404 | 405 | .col-md-9, 406 | .row.cols-md-9 > * { 407 | max-width: 75%; 408 | flex-basis: 75%; } 409 | 410 | .col-md-offset-8 { 411 | margin-left: 66.6666666667%; } 412 | 413 | .col-md-10, 414 | .row.cols-md-10 > * { 415 | max-width: 83.3333333333%; 416 | flex-basis: 83.3333333333%; } 417 | 418 | .col-md-offset-9 { 419 | margin-left: 75%; } 420 | 421 | .col-md-11, 422 | .row.cols-md-11 > * { 423 | max-width: 91.6666666667%; 424 | flex-basis: 91.6666666667%; } 425 | 426 | .col-md-offset-10 { 427 | margin-left: 83.3333333333%; } 428 | 429 | .col-md-12, 430 | .row.cols-md-12 > * { 431 | max-width: 100%; 432 | flex-basis: 100%; } 433 | 434 | .col-md-offset-11 { 435 | margin-left: 91.6666666667%; } 436 | 437 | .col-md-normal { 438 | order: initial; } 439 | 440 | .col-md-first { 441 | order: -999; } 442 | 443 | .col-md-last { 444 | order: 999; } } 445 | @media screen and (min-width: 1280px) { 446 | .col-lg, 447 | [class^='col-lg-'], 448 | [class^='col-lg-offset-'], 449 | .row[class*='cols-lg-'] > * { 450 | box-sizing: border-box; 451 | flex: 0 0 auto; 452 | padding: 0 calc(var(--universal-padding) / 2); } 453 | 454 | .col-lg, 455 | .row.cols-lg > * { 456 | max-width: 100%; 457 | flex-grow: 1; 458 | flex-basis: 0; } 459 | 460 | .col-lg-1, 461 | .row.cols-lg-1 > * { 462 | max-width: 8.3333333333%; 463 | flex-basis: 8.3333333333%; } 464 | 465 | .col-lg-offset-0 { 466 | margin-left: 0; } 467 | 468 | .col-lg-2, 469 | .row.cols-lg-2 > * { 470 | max-width: 16.6666666667%; 471 | flex-basis: 16.6666666667%; } 472 | 473 | .col-lg-offset-1 { 474 | margin-left: 8.3333333333%; } 475 | 476 | .col-lg-3, 477 | .row.cols-lg-3 > * { 478 | max-width: 25%; 479 | flex-basis: 25%; } 480 | 481 | .col-lg-offset-2 { 482 | margin-left: 16.6666666667%; } 483 | 484 | .col-lg-4, 485 | .row.cols-lg-4 > * { 486 | max-width: 33.3333333333%; 487 | flex-basis: 33.3333333333%; } 488 | 489 | .col-lg-offset-3 { 490 | margin-left: 25%; } 491 | 492 | .col-lg-5, 493 | .row.cols-lg-5 > * { 494 | max-width: 41.6666666667%; 495 | flex-basis: 41.6666666667%; } 496 | 497 | .col-lg-offset-4 { 498 | margin-left: 33.3333333333%; } 499 | 500 | .col-lg-6, 501 | .row.cols-lg-6 > * { 502 | max-width: 50%; 503 | flex-basis: 50%; } 504 | 505 | .col-lg-offset-5 { 506 | margin-left: 41.6666666667%; } 507 | 508 | .col-lg-7, 509 | .row.cols-lg-7 > * { 510 | max-width: 58.3333333333%; 511 | flex-basis: 58.3333333333%; } 512 | 513 | .col-lg-offset-6 { 514 | margin-left: 50%; } 515 | 516 | .col-lg-8, 517 | .row.cols-lg-8 > * { 518 | max-width: 66.6666666667%; 519 | flex-basis: 66.6666666667%; } 520 | 521 | .col-lg-offset-7 { 522 | margin-left: 58.3333333333%; } 523 | 524 | .col-lg-9, 525 | .row.cols-lg-9 > * { 526 | max-width: 75%; 527 | flex-basis: 75%; } 528 | 529 | .col-lg-offset-8 { 530 | margin-left: 66.6666666667%; } 531 | 532 | .col-lg-10, 533 | .row.cols-lg-10 > * { 534 | max-width: 83.3333333333%; 535 | flex-basis: 83.3333333333%; } 536 | 537 | .col-lg-offset-9 { 538 | margin-left: 75%; } 539 | 540 | .col-lg-11, 541 | .row.cols-lg-11 > * { 542 | max-width: 91.6666666667%; 543 | flex-basis: 91.6666666667%; } 544 | 545 | .col-lg-offset-10 { 546 | margin-left: 83.3333333333%; } 547 | 548 | .col-lg-12, 549 | .row.cols-lg-12 > * { 550 | max-width: 100%; 551 | flex-basis: 100%; } 552 | 553 | .col-lg-offset-11 { 554 | margin-left: 91.6666666667%; } 555 | 556 | .col-lg-normal { 557 | order: initial; } 558 | 559 | .col-lg-first { 560 | order: -999; } 561 | 562 | .col-lg-last { 563 | order: 999; } } 564 | /* Card component CSS variable definitions */ 565 | :root { 566 | --card-back-color: #3cb4e6; 567 | --card-fore-color: #03234b; 568 | --card-border-color: #03234b; } 569 | 570 | .card { 571 | display: flex; 572 | flex-direction: column; 573 | justify-content: space-between; 574 | align-self: center; 575 | position: relative; 576 | width: 100%; 577 | background: var(--card-back-color); 578 | color: var(--card-fore-color); 579 | border: 0.0714285714rem solid var(--card-border-color); 580 | border-radius: var(--universal-border-radius); 581 | margin: var(--universal-margin); 582 | overflow: hidden; } 583 | @media screen and (min-width: 320px) { 584 | .card { 585 | max-width: 320px; } } 586 | .card > .sectione { 587 | background: var(--card-back-color); 588 | color: var(--card-fore-color); 589 | box-sizing: border-box; 590 | margin: 0; 591 | border: 0; 592 | border-radius: 0; 593 | border-bottom: 0.0714285714rem solid var(--card-border-color); 594 | padding: var(--universal-padding); 595 | width: 100%; } 596 | .card > .sectione.media { 597 | height: 200px; 598 | padding: 0; 599 | -o-object-fit: cover; 600 | object-fit: cover; } 601 | .card > .sectione:last-child { 602 | border-bottom: 0; } 603 | 604 | /* 605 | Custom elements for card elements. 606 | */ 607 | @media screen and (min-width: 240px) { 608 | .card.small { 609 | max-width: 240px; } } 610 | @media screen and (min-width: 480px) { 611 | .card.large { 612 | max-width: 480px; } } 613 | .card.fluid { 614 | max-width: 100%; 615 | width: auto; } 616 | 617 | .card.warning { 618 | --card-back-color: #e5b8b7; 619 | --card-fore-color: #3b234b; 620 | --card-border-color: #8c0078; } 621 | 622 | .card.error { 623 | --card-back-color: #464650; 624 | --card-fore-color: #ffffff; 625 | --card-border-color: #8c0078; } 626 | 627 | .card > .sectione.dark { 628 | --card-back-color: #3b234b; 629 | --card-fore-color: #ffffff; } 630 | 631 | .card > .sectione.double-padded { 632 | padding: calc(1.5 * var(--universal-padding)); } 633 | 634 | /* 635 | Definitions for forms and input elements. 636 | */ 637 | /* Input_control module CSS variable definitions */ 638 | :root { 639 | --form-back-color: #ffe97f; 640 | --form-fore-color: #03234b; 641 | --form-border-color: #3cb4e6; 642 | --input-back-color: #ffffff; 643 | --input-fore-color: #03234b; 644 | --input-border-color: #3cb4e6; 645 | --input-focus-color: #0288d1; 646 | --input-invalid-color: #d32f2f; 647 | --button-back-color: #e2e2e2; 648 | --button-hover-back-color: #dcdcdc; 649 | --button-fore-color: #212121; 650 | --button-border-color: transparent; 651 | --button-hover-border-color: transparent; 652 | --button-group-border-color: rgba(124, 124, 124, 0.54); } 653 | 654 | form { 655 | background: var(--form-back-color); 656 | color: var(--form-fore-color); 657 | border: 0.0714285714rem solid var(--form-border-color); 658 | border-radius: var(--universal-border-radius); 659 | margin: var(--universal-margin); 660 | padding: calc(2 * var(--universal-padding)) var(--universal-padding); } 661 | 662 | fieldset { 663 | border: 0.0714285714rem solid var(--form-border-color); 664 | border-radius: var(--universal-border-radius); 665 | margin: calc(var(--universal-margin) / 4); 666 | padding: var(--universal-padding); } 667 | 668 | legend { 669 | box-sizing: border-box; 670 | display: table; 671 | max-width: 100%; 672 | white-space: normal; 673 | font-weight: 500; 674 | padding: calc(var(--universal-padding) / 2); } 675 | 676 | label { 677 | padding: calc(var(--universal-padding) / 2) var(--universal-padding); } 678 | 679 | .input-group { 680 | display: inline-block; } 681 | .input-group.fluid { 682 | display: flex; 683 | align-items: center; 684 | justify-content: center; } 685 | .input-group.fluid > input { 686 | max-width: 100%; 687 | flex-grow: 1; 688 | flex-basis: 0px; } 689 | @media screen and (max-width: 499px) { 690 | .input-group.fluid { 691 | align-items: stretch; 692 | flex-direction: column; } } 693 | .input-group.vertical { 694 | display: flex; 695 | align-items: stretch; 696 | flex-direction: column; } 697 | .input-group.vertical > input { 698 | max-width: 100%; 699 | flex-grow: 1; 700 | flex-basis: 0px; } 701 | 702 | [type="number"]::-webkit-inner-spin-button, [type="number"]::-webkit-outer-spin-button { 703 | height: auto; } 704 | 705 | [type="search"] { 706 | -webkit-appearance: textfield; 707 | outline-offset: -2px; } 708 | 709 | [type="search"]::-webkit-search-cancel-button, 710 | [type="search"]::-webkit-search-decoration { 711 | -webkit-appearance: none; } 712 | 713 | input:not([type]), [type="text"], [type="email"], [type="number"], [type="search"], 714 | [type="password"], [type="url"], [type="tel"], [type="checkbox"], [type="radio"], textarea, select { 715 | box-sizing: border-box; 716 | background: var(--input-back-color); 717 | color: var(--input-fore-color); 718 | border: 0.0714285714rem solid var(--input-border-color); 719 | border-radius: var(--universal-border-radius); 720 | margin: calc(var(--universal-margin) / 2); 721 | padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } 722 | 723 | input:not([type="button"]):not([type="submit"]):not([type="reset"]):hover, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus, textarea:hover, textarea:focus, select:hover, select:focus { 724 | border-color: var(--input-focus-color); 725 | box-shadow: none; } 726 | input:not([type="button"]):not([type="submit"]):not([type="reset"]):invalid, input:not([type="button"]):not([type="submit"]):not([type="reset"]):focus:invalid, textarea:invalid, textarea:focus:invalid, select:invalid, select:focus:invalid { 727 | border-color: var(--input-invalid-color); 728 | box-shadow: none; } 729 | input:not([type="button"]):not([type="submit"]):not([type="reset"])[readonly], textarea[readonly], select[readonly] { 730 | background: var(--secondary-back-color); } 731 | 732 | select { 733 | max-width: 100%; } 734 | 735 | option { 736 | overflow: hidden; 737 | text-overflow: ellipsis; } 738 | 739 | [type="checkbox"], [type="radio"] { 740 | -webkit-appearance: none; 741 | -moz-appearance: none; 742 | appearance: none; 743 | position: relative; 744 | height: calc(1rem + var(--universal-padding) / 2); 745 | width: calc(1rem + var(--universal-padding) / 2); 746 | vertical-align: text-bottom; 747 | padding: 0; 748 | flex-basis: calc(1rem + var(--universal-padding) / 2) !important; 749 | flex-grow: 0 !important; } 750 | [type="checkbox"]:checked:before, [type="radio"]:checked:before { 751 | position: absolute; } 752 | 753 | [type="checkbox"]:checked:before { 754 | content: '\2713'; 755 | font-family: sans-serif; 756 | font-size: calc(1rem + var(--universal-padding) / 2); 757 | top: calc(0rem - var(--universal-padding)); 758 | left: calc(var(--universal-padding) / 4); } 759 | 760 | [type="radio"] { 761 | border-radius: 100%; } 762 | [type="radio"]:checked:before { 763 | border-radius: 100%; 764 | content: ''; 765 | top: calc(0.0714285714rem + var(--universal-padding) / 2); 766 | left: calc(0.0714285714rem + var(--universal-padding) / 2); 767 | background: var(--input-fore-color); 768 | width: 0.5rem; 769 | height: 0.5rem; } 770 | 771 | :placeholder-shown { 772 | color: var(--input-fore-color); } 773 | 774 | ::-ms-placeholder { 775 | color: var(--input-fore-color); 776 | opacity: 0.54; } 777 | 778 | button::-moz-focus-inner, [type="button"]::-moz-focus-inner, [type="reset"]::-moz-focus-inner, [type="submit"]::-moz-focus-inner { 779 | border-style: none; 780 | padding: 0; } 781 | 782 | button, html [type="button"], [type="reset"], [type="submit"] { 783 | -webkit-appearance: button; } 784 | 785 | button { 786 | overflow: visible; 787 | text-transform: none; } 788 | 789 | button, [type="button"], [type="submit"], [type="reset"], 790 | a.button, label.button, .button, 791 | a[role="button"], label[role="button"], [role="button"] { 792 | display: inline-block; 793 | background: var(--button-back-color); 794 | color: var(--button-fore-color); 795 | border: 0.0714285714rem solid var(--button-border-color); 796 | border-radius: var(--universal-border-radius); 797 | padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); 798 | margin: var(--universal-margin); 799 | text-decoration: none; 800 | cursor: pointer; 801 | transition: background 0.3s; } 802 | button:hover, button:focus, [type="button"]:hover, [type="button"]:focus, [type="submit"]:hover, [type="submit"]:focus, [type="reset"]:hover, [type="reset"]:focus, 803 | a.button:hover, 804 | a.button:focus, label.button:hover, label.button:focus, .button:hover, .button:focus, 805 | a[role="button"]:hover, 806 | a[role="button"]:focus, label[role="button"]:hover, label[role="button"]:focus, [role="button"]:hover, [role="button"]:focus { 807 | background: var(--button-hover-back-color); 808 | border-color: var(--button-hover-border-color); } 809 | 810 | input:disabled, input[disabled], textarea:disabled, textarea[disabled], select:disabled, select[disabled], button:disabled, button[disabled], .button:disabled, .button[disabled], [role="button"]:disabled, [role="button"][disabled] { 811 | cursor: not-allowed; 812 | opacity: 0.75; } 813 | 814 | .button-group { 815 | display: flex; 816 | border: 0.0714285714rem solid var(--button-group-border-color); 817 | border-radius: var(--universal-border-radius); 818 | margin: var(--universal-margin); } 819 | .button-group > button, .button-group [type="button"], .button-group > [type="submit"], .button-group > [type="reset"], .button-group > .button, .button-group > [role="button"] { 820 | margin: 0; 821 | max-width: 100%; 822 | flex: 1 1 auto; 823 | text-align: center; 824 | border: 0; 825 | border-radius: 0; 826 | box-shadow: none; } 827 | .button-group > :not(:first-child) { 828 | border-left: 0.0714285714rem solid var(--button-group-border-color); } 829 | @media screen and (max-width: 499px) { 830 | .button-group { 831 | flex-direction: column; } 832 | .button-group > :not(:first-child) { 833 | border: 0; 834 | border-top: 0.0714285714rem solid var(--button-group-border-color); } } 835 | 836 | /* 837 | Custom elements for forms and input elements. 838 | */ 839 | button.primary, [type="button"].primary, [type="submit"].primary, [type="reset"].primary, .button.primary, [role="button"].primary { 840 | --button-back-color: #1976d2; 841 | --button-fore-color: #f8f8f8; } 842 | button.primary:hover, button.primary:focus, [type="button"].primary:hover, [type="button"].primary:focus, [type="submit"].primary:hover, [type="submit"].primary:focus, [type="reset"].primary:hover, [type="reset"].primary:focus, .button.primary:hover, .button.primary:focus, [role="button"].primary:hover, [role="button"].primary:focus { 843 | --button-hover-back-color: #1565c0; } 844 | 845 | button.secondary, [type="button"].secondary, [type="submit"].secondary, [type="reset"].secondary, .button.secondary, [role="button"].secondary { 846 | --button-back-color: #d32f2f; 847 | --button-fore-color: #f8f8f8; } 848 | button.secondary:hover, button.secondary:focus, [type="button"].secondary:hover, [type="button"].secondary:focus, [type="submit"].secondary:hover, [type="submit"].secondary:focus, [type="reset"].secondary:hover, [type="reset"].secondary:focus, .button.secondary:hover, .button.secondary:focus, [role="button"].secondary:hover, [role="button"].secondary:focus { 849 | --button-hover-back-color: #c62828; } 850 | 851 | button.tertiary, [type="button"].tertiary, [type="submit"].tertiary, [type="reset"].tertiary, .button.tertiary, [role="button"].tertiary { 852 | --button-back-color: #308732; 853 | --button-fore-color: #f8f8f8; } 854 | button.tertiary:hover, button.tertiary:focus, [type="button"].tertiary:hover, [type="button"].tertiary:focus, [type="submit"].tertiary:hover, [type="submit"].tertiary:focus, [type="reset"].tertiary:hover, [type="reset"].tertiary:focus, .button.tertiary:hover, .button.tertiary:focus, [role="button"].tertiary:hover, [role="button"].tertiary:focus { 855 | --button-hover-back-color: #277529; } 856 | 857 | button.inverse, [type="button"].inverse, [type="submit"].inverse, [type="reset"].inverse, .button.inverse, [role="button"].inverse { 858 | --button-back-color: #212121; 859 | --button-fore-color: #f8f8f8; } 860 | button.inverse:hover, button.inverse:focus, [type="button"].inverse:hover, [type="button"].inverse:focus, [type="submit"].inverse:hover, [type="submit"].inverse:focus, [type="reset"].inverse:hover, [type="reset"].inverse:focus, .button.inverse:hover, .button.inverse:focus, [role="button"].inverse:hover, [role="button"].inverse:focus { 861 | --button-hover-back-color: #111; } 862 | 863 | button.small, [type="button"].small, [type="submit"].small, [type="reset"].small, .button.small, [role="button"].small { 864 | padding: calc(0.5 * var(--universal-padding)) calc(0.75 * var(--universal-padding)); 865 | margin: var(--universal-margin); } 866 | 867 | button.large, [type="button"].large, [type="submit"].large, [type="reset"].large, .button.large, [role="button"].large { 868 | padding: calc(1.5 * var(--universal-padding)) calc(2 * var(--universal-padding)); 869 | margin: var(--universal-margin); } 870 | 871 | /* 872 | Definitions for navigation elements. 873 | */ 874 | /* Navigation module CSS variable definitions */ 875 | :root { 876 | --header-back-color: #03234b; 877 | --header-hover-back-color: #ffd200; 878 | --header-fore-color: #ffffff; 879 | --header-border-color: #3cb4e6; 880 | --nav-back-color: #ffffff; 881 | --nav-hover-back-color: #ffe97f; 882 | --nav-fore-color: #e6007e; 883 | --nav-border-color: #3cb4e6; 884 | --nav-link-color: #3cb4e6; 885 | --footer-fore-color: #ffffff; 886 | --footer-back-color: #03234b; 887 | --footer-border-color: #3cb4e6; 888 | --footer-link-color: #3cb4e6; 889 | --drawer-back-color: #ffffff; 890 | --drawer-hover-back-color: #ffe97f; 891 | --drawer-border-color: #3cb4e6; 892 | --drawer-close-color: #e6007e; } 893 | 894 | header { 895 | height: 2.75rem; 896 | background: var(--header-back-color); 897 | color: var(--header-fore-color); 898 | border-bottom: 0.0714285714rem solid var(--header-border-color); 899 | padding: calc(var(--universal-padding) / 4) 0; 900 | white-space: nowrap; 901 | overflow-x: auto; 902 | overflow-y: hidden; } 903 | header.row { 904 | box-sizing: content-box; } 905 | header .logo { 906 | color: var(--header-fore-color); 907 | font-size: 1.75rem; 908 | padding: var(--universal-padding) calc(2 * var(--universal-padding)); 909 | text-decoration: none; } 910 | header button, header [type="button"], header .button, header [role="button"] { 911 | box-sizing: border-box; 912 | position: relative; 913 | top: calc(0rem - var(--universal-padding) / 4); 914 | height: calc(3.1875rem + var(--universal-padding) / 2); 915 | background: var(--header-back-color); 916 | line-height: calc(3.1875rem - var(--universal-padding) * 1.5); 917 | text-align: center; 918 | color: var(--header-fore-color); 919 | border: 0; 920 | border-radius: 0; 921 | margin: 0; 922 | text-transform: uppercase; } 923 | header button:hover, header button:focus, header [type="button"]:hover, header [type="button"]:focus, header .button:hover, header .button:focus, header [role="button"]:hover, header [role="button"]:focus { 924 | background: var(--header-hover-back-color); } 925 | 926 | nav { 927 | background: var(--nav-back-color); 928 | color: var(--nav-fore-color); 929 | border: 0.0714285714rem solid var(--nav-border-color); 930 | border-radius: var(--universal-border-radius); 931 | margin: var(--universal-margin); } 932 | nav * { 933 | padding: var(--universal-padding) calc(1.5 * var(--universal-padding)); } 934 | nav a, nav a:visited { 935 | display: block; 936 | color: var(--nav-link-color); 937 | border-radius: var(--universal-border-radius); 938 | transition: background 0.3s; } 939 | nav a:hover, nav a:focus, nav a:visited:hover, nav a:visited:focus { 940 | text-decoration: none; 941 | background: var(--nav-hover-back-color); } 942 | nav .sublink-1 { 943 | position: relative; 944 | margin-left: calc(2 * var(--universal-padding)); } 945 | nav .sublink-1:before { 946 | position: absolute; 947 | left: calc(var(--universal-padding) - 1 * var(--universal-padding)); 948 | top: -0.0714285714rem; 949 | content: ''; 950 | height: 100%; 951 | border: 0.0714285714rem solid var(--nav-border-color); 952 | border-left: 0; } 953 | nav .sublink-2 { 954 | position: relative; 955 | margin-left: calc(4 * var(--universal-padding)); } 956 | nav .sublink-2:before { 957 | position: absolute; 958 | left: calc(var(--universal-padding) - 3 * var(--universal-padding)); 959 | top: -0.0714285714rem; 960 | content: ''; 961 | height: 100%; 962 | border: 0.0714285714rem solid var(--nav-border-color); 963 | border-left: 0; } 964 | 965 | footer { 966 | background: var(--footer-back-color); 967 | color: var(--footer-fore-color); 968 | border-top: 0.0714285714rem solid var(--footer-border-color); 969 | padding: calc(2 * var(--universal-padding)) var(--universal-padding); 970 | font-size: 0.875rem; } 971 | footer a, footer a:visited { 972 | color: var(--footer-link-color); } 973 | 974 | header.sticky { 975 | position: -webkit-sticky; 976 | position: sticky; 977 | z-index: 1101; 978 | top: 0; } 979 | 980 | footer.sticky { 981 | position: -webkit-sticky; 982 | position: sticky; 983 | z-index: 1101; 984 | bottom: 0; } 985 | 986 | .drawer-toggle:before { 987 | display: inline-block; 988 | position: relative; 989 | vertical-align: bottom; 990 | content: '\00a0\2261\00a0'; 991 | font-family: sans-serif; 992 | font-size: 1.5em; } 993 | @media screen and (min-width: 500px) { 994 | .drawer-toggle:not(.persistent) { 995 | display: none; } } 996 | 997 | [type="checkbox"].drawer { 998 | height: 1px; 999 | width: 1px; 1000 | margin: -1px; 1001 | overflow: hidden; 1002 | position: absolute; 1003 | clip: rect(0 0 0 0); 1004 | -webkit-clip-path: inset(100%); 1005 | clip-path: inset(100%); } 1006 | [type="checkbox"].drawer + * { 1007 | display: block; 1008 | box-sizing: border-box; 1009 | position: fixed; 1010 | top: 0; 1011 | width: 320px; 1012 | height: 100vh; 1013 | overflow-y: auto; 1014 | background: var(--drawer-back-color); 1015 | border: 0.0714285714rem solid var(--drawer-border-color); 1016 | border-radius: 0; 1017 | margin: 0; 1018 | z-index: 1110; 1019 | right: -320px; 1020 | transition: right 0.3s; } 1021 | [type="checkbox"].drawer + * .drawer-close { 1022 | position: absolute; 1023 | top: var(--universal-margin); 1024 | right: var(--universal-margin); 1025 | z-index: 1111; 1026 | width: 2rem; 1027 | height: 2rem; 1028 | border-radius: var(--universal-border-radius); 1029 | padding: var(--universal-padding); 1030 | margin: 0; 1031 | cursor: pointer; 1032 | transition: background 0.3s; } 1033 | [type="checkbox"].drawer + * .drawer-close:before { 1034 | display: block; 1035 | content: '\00D7'; 1036 | color: var(--drawer-close-color); 1037 | position: relative; 1038 | font-family: sans-serif; 1039 | font-size: 2rem; 1040 | line-height: 1; 1041 | text-align: center; } 1042 | [type="checkbox"].drawer + * .drawer-close:hover, [type="checkbox"].drawer + * .drawer-close:focus { 1043 | background: var(--drawer-hover-back-color); } 1044 | @media screen and (max-width: 320px) { 1045 | [type="checkbox"].drawer + * { 1046 | width: 100%; } } 1047 | [type="checkbox"].drawer:checked + * { 1048 | right: 0; } 1049 | @media screen and (min-width: 500px) { 1050 | [type="checkbox"].drawer:not(.persistent) + * { 1051 | position: static; 1052 | height: 100%; 1053 | z-index: 1100; } 1054 | [type="checkbox"].drawer:not(.persistent) + * .drawer-close { 1055 | display: none; } } 1056 | 1057 | /* 1058 | Definitions for the responsive table component. 1059 | */ 1060 | /* Table module CSS variable definitions. */ 1061 | :root { 1062 | --table-border-color: #03234b; 1063 | --table-border-separator-color: #03234b; 1064 | --table-head-back-color: #03234b; 1065 | --table-head-fore-color: #ffffff; 1066 | --table-body-back-color: #ffffff; 1067 | --table-body-fore-color: #03234b; 1068 | --table-body-alt-back-color: #f4f4f4; } 1069 | 1070 | table { 1071 | border-collapse: separate; 1072 | border-spacing: 0; 1073 | margin: 0; 1074 | display: flex; 1075 | flex: 0 1 auto; 1076 | flex-flow: row wrap; 1077 | padding: var(--universal-padding); 1078 | padding-top: 0; } 1079 | table caption { 1080 | font-size: 1rem; 1081 | margin: calc(2 * var(--universal-margin)) 0; 1082 | max-width: 100%; 1083 | flex: 0 0 100%; } 1084 | table thead, table tbody { 1085 | display: flex; 1086 | flex-flow: row wrap; 1087 | border: 0.0714285714rem solid var(--table-border-color); } 1088 | table thead { 1089 | z-index: 999; 1090 | border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; 1091 | border-bottom: 0.0714285714rem solid var(--table-border-separator-color); } 1092 | table tbody { 1093 | border-top: 0; 1094 | margin-top: calc(0 - var(--universal-margin)); 1095 | border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } 1096 | table tr { 1097 | display: flex; 1098 | padding: 0; } 1099 | table th, table td { 1100 | padding: calc(0.5 * var(--universal-padding)); 1101 | font-size: 0.9rem; } 1102 | table th { 1103 | text-align: left; 1104 | background: var(--table-head-back-color); 1105 | color: var(--table-head-fore-color); } 1106 | table td { 1107 | background: var(--table-body-back-color); 1108 | color: var(--table-body-fore-color); 1109 | border-top: 0.0714285714rem solid var(--table-border-color); } 1110 | 1111 | table:not(.horizontal) { 1112 | overflow: auto; 1113 | max-height: 100%; } 1114 | table:not(.horizontal) thead, table:not(.horizontal) tbody { 1115 | max-width: 100%; 1116 | flex: 0 0 100%; } 1117 | table:not(.horizontal) tr { 1118 | flex-flow: row wrap; 1119 | flex: 0 0 100%; } 1120 | table:not(.horizontal) th, table:not(.horizontal) td { 1121 | flex: 1 0 0%; 1122 | overflow: hidden; 1123 | text-overflow: ellipsis; } 1124 | table:not(.horizontal) thead { 1125 | position: sticky; 1126 | top: 0; } 1127 | table:not(.horizontal) tbody tr:first-child td { 1128 | border-top: 0; } 1129 | 1130 | table.horizontal { 1131 | border: 0; } 1132 | table.horizontal thead, table.horizontal tbody { 1133 | border: 0; 1134 | flex: .2 0 0; 1135 | flex-flow: row nowrap; } 1136 | table.horizontal tbody { 1137 | overflow: auto; 1138 | justify-content: space-between; 1139 | flex: .8 0 0; 1140 | margin-left: 0; 1141 | padding-bottom: calc(var(--universal-padding) / 4); } 1142 | table.horizontal tr { 1143 | flex-direction: column; 1144 | flex: 1 0 auto; } 1145 | table.horizontal th, table.horizontal td { 1146 | width: auto; 1147 | border: 0; 1148 | border-bottom: 0.0714285714rem solid var(--table-border-color); } 1149 | table.horizontal th:not(:first-child), table.horizontal td:not(:first-child) { 1150 | border-top: 0; } 1151 | table.horizontal th { 1152 | text-align: right; 1153 | border-left: 0.0714285714rem solid var(--table-border-color); 1154 | border-right: 0.0714285714rem solid var(--table-border-separator-color); } 1155 | table.horizontal thead tr:first-child { 1156 | padding-left: 0; } 1157 | table.horizontal th:first-child, table.horizontal td:first-child { 1158 | border-top: 0.0714285714rem solid var(--table-border-color); } 1159 | table.horizontal tbody tr:last-child td { 1160 | border-right: 0.0714285714rem solid var(--table-border-color); } 1161 | table.horizontal tbody tr:last-child td:first-child { 1162 | border-top-right-radius: 0.25rem; } 1163 | table.horizontal tbody tr:last-child td:last-child { 1164 | border-bottom-right-radius: 0.25rem; } 1165 | table.horizontal thead tr:first-child th:first-child { 1166 | border-top-left-radius: 0.25rem; } 1167 | table.horizontal thead tr:first-child th:last-child { 1168 | border-bottom-left-radius: 0.25rem; } 1169 | 1170 | @media screen and (max-width: 499px) { 1171 | table, table.horizontal { 1172 | border-collapse: collapse; 1173 | border: 0; 1174 | width: 100%; 1175 | display: table; } 1176 | table thead, table th, table.horizontal thead, table.horizontal th { 1177 | border: 0; 1178 | height: 1px; 1179 | width: 1px; 1180 | margin: -1px; 1181 | overflow: hidden; 1182 | padding: 0; 1183 | position: absolute; 1184 | clip: rect(0 0 0 0); 1185 | -webkit-clip-path: inset(100%); 1186 | clip-path: inset(100%); } 1187 | table tbody, table.horizontal tbody { 1188 | border: 0; 1189 | display: table-row-group; } 1190 | table tr, table.horizontal tr { 1191 | display: block; 1192 | border: 0.0714285714rem solid var(--table-border-color); 1193 | border-radius: var(--universal-border-radius); 1194 | background: #ffffff; 1195 | padding: var(--universal-padding); 1196 | margin: var(--universal-margin); 1197 | margin-bottom: calc(1 * var(--universal-margin)); } 1198 | table th, table td, table.horizontal th, table.horizontal td { 1199 | width: auto; } 1200 | table td, table.horizontal td { 1201 | display: block; 1202 | border: 0; 1203 | text-align: right; } 1204 | table td:before, table.horizontal td:before { 1205 | content: attr(data-label); 1206 | float: left; 1207 | font-weight: 600; } 1208 | table th:first-child, table td:first-child, table.horizontal th:first-child, table.horizontal td:first-child { 1209 | border-top: 0; } 1210 | table tbody tr:last-child td, table.horizontal tbody tr:last-child td { 1211 | border-right: 0; } } 1212 | table tr:nth-of-type(2n) > td { 1213 | background: var(--table-body-alt-back-color); } 1214 | 1215 | @media screen and (max-width: 500px) { 1216 | table tr:nth-of-type(2n) { 1217 | background: var(--table-body-alt-back-color); } } 1218 | :root { 1219 | --table-body-hover-back-color: #90caf9; } 1220 | 1221 | table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { 1222 | background: var(--table-body-hover-back-color); } 1223 | 1224 | @media screen and (max-width: 500px) { 1225 | table.hoverable tr:hover, table.hoverable tr:hover > td, table.hoverable tr:focus, table.hoverable tr:focus > td { 1226 | background: var(--table-body-hover-back-color); } } 1227 | /* 1228 | Definitions for contextual background elements, toasts and tooltips. 1229 | */ 1230 | /* Contextual module CSS variable definitions */ 1231 | :root { 1232 | --mark-back-color: #3cb4e6; 1233 | --mark-fore-color: #ffffff; } 1234 | 1235 | mark { 1236 | background: var(--mark-back-color); 1237 | color: var(--mark-fore-color); 1238 | font-size: 0.95em; 1239 | line-height: 1em; 1240 | border-radius: var(--universal-border-radius); 1241 | padding: calc(var(--universal-padding) / 4) var(--universal-padding); } 1242 | mark.inline-block { 1243 | display: inline-block; 1244 | font-size: 1em; 1245 | line-height: 1.4; 1246 | padding: calc(var(--universal-padding) / 2) var(--universal-padding); } 1247 | 1248 | :root { 1249 | --toast-back-color: #424242; 1250 | --toast-fore-color: #fafafa; } 1251 | 1252 | .toast { 1253 | position: fixed; 1254 | bottom: calc(var(--universal-margin) * 3); 1255 | left: 50%; 1256 | transform: translate(-50%, -50%); 1257 | z-index: 1111; 1258 | color: var(--toast-fore-color); 1259 | background: var(--toast-back-color); 1260 | border-radius: calc(var(--universal-border-radius) * 16); 1261 | padding: var(--universal-padding) calc(var(--universal-padding) * 3); } 1262 | 1263 | :root { 1264 | --tooltip-back-color: #212121; 1265 | --tooltip-fore-color: #fafafa; } 1266 | 1267 | .tooltip { 1268 | position: relative; 1269 | display: inline-block; } 1270 | .tooltip:before, .tooltip:after { 1271 | position: absolute; 1272 | opacity: 0; 1273 | clip: rect(0 0 0 0); 1274 | -webkit-clip-path: inset(100%); 1275 | clip-path: inset(100%); 1276 | transition: all 0.3s; 1277 | z-index: 1010; 1278 | left: 50%; } 1279 | .tooltip:not(.bottom):before, .tooltip:not(.bottom):after { 1280 | bottom: 75%; } 1281 | .tooltip.bottom:before, .tooltip.bottom:after { 1282 | top: 75%; } 1283 | .tooltip:hover:before, .tooltip:hover:after, .tooltip:focus:before, .tooltip:focus:after { 1284 | opacity: 1; 1285 | clip: auto; 1286 | -webkit-clip-path: inset(0%); 1287 | clip-path: inset(0%); } 1288 | .tooltip:before { 1289 | content: ''; 1290 | background: transparent; 1291 | border: var(--universal-margin) solid transparent; 1292 | left: calc(50% - var(--universal-margin)); } 1293 | .tooltip:not(.bottom):before { 1294 | border-top-color: #212121; } 1295 | .tooltip.bottom:before { 1296 | border-bottom-color: #212121; } 1297 | .tooltip:after { 1298 | content: attr(aria-label); 1299 | color: var(--tooltip-fore-color); 1300 | background: var(--tooltip-back-color); 1301 | border-radius: var(--universal-border-radius); 1302 | padding: var(--universal-padding); 1303 | white-space: nowrap; 1304 | transform: translateX(-50%); } 1305 | .tooltip:not(.bottom):after { 1306 | margin-bottom: calc(2 * var(--universal-margin)); } 1307 | .tooltip.bottom:after { 1308 | margin-top: calc(2 * var(--universal-margin)); } 1309 | 1310 | :root { 1311 | --modal-overlay-color: rgba(0, 0, 0, 0.45); 1312 | --modal-close-color: #e6007e; 1313 | --modal-close-hover-color: #ffe97f; } 1314 | 1315 | [type="checkbox"].modal { 1316 | height: 1px; 1317 | width: 1px; 1318 | margin: -1px; 1319 | overflow: hidden; 1320 | position: absolute; 1321 | clip: rect(0 0 0 0); 1322 | -webkit-clip-path: inset(100%); 1323 | clip-path: inset(100%); } 1324 | [type="checkbox"].modal + div { 1325 | position: fixed; 1326 | top: 0; 1327 | left: 0; 1328 | display: none; 1329 | width: 100vw; 1330 | height: 100vh; 1331 | background: var(--modal-overlay-color); } 1332 | [type="checkbox"].modal + div .card { 1333 | margin: 0 auto; 1334 | max-height: 50vh; 1335 | overflow: auto; } 1336 | [type="checkbox"].modal + div .card .modal-close { 1337 | position: absolute; 1338 | top: 0; 1339 | right: 0; 1340 | width: 1.75rem; 1341 | height: 1.75rem; 1342 | border-radius: var(--universal-border-radius); 1343 | padding: var(--universal-padding); 1344 | margin: 0; 1345 | cursor: pointer; 1346 | transition: background 0.3s; } 1347 | [type="checkbox"].modal + div .card .modal-close:before { 1348 | display: block; 1349 | content: '\00D7'; 1350 | color: var(--modal-close-color); 1351 | position: relative; 1352 | font-family: sans-serif; 1353 | font-size: 1.75rem; 1354 | line-height: 1; 1355 | text-align: center; } 1356 | [type="checkbox"].modal + div .card .modal-close:hover, [type="checkbox"].modal + div .card .modal-close:focus { 1357 | background: var(--modal-close-hover-color); } 1358 | [type="checkbox"].modal:checked + div { 1359 | display: flex; 1360 | flex: 0 1 auto; 1361 | z-index: 1200; } 1362 | [type="checkbox"].modal:checked + div .card .modal-close { 1363 | z-index: 1211; } 1364 | 1365 | :root { 1366 | --collapse-label-back-color: #03234b; 1367 | --collapse-label-fore-color: #ffffff; 1368 | --collapse-label-hover-back-color: #3cb4e6; 1369 | --collapse-selected-label-back-color: #3cb4e6; 1370 | --collapse-border-color: var(--collapse-label-back-color); 1371 | --collapse-selected-border-color: #ceecf8; 1372 | --collapse-content-back-color: #ffffff; 1373 | --collapse-selected-label-border-color: #3cb4e6; } 1374 | 1375 | .collapse { 1376 | width: calc(100% - 2 * var(--universal-margin)); 1377 | opacity: 1; 1378 | display: flex; 1379 | flex-direction: column; 1380 | margin: var(--universal-margin); 1381 | border-radius: var(--universal-border-radius); } 1382 | .collapse > [type="radio"], .collapse > [type="checkbox"] { 1383 | height: 1px; 1384 | width: 1px; 1385 | margin: -1px; 1386 | overflow: hidden; 1387 | position: absolute; 1388 | clip: rect(0 0 0 0); 1389 | -webkit-clip-path: inset(100%); 1390 | clip-path: inset(100%); } 1391 | .collapse > label { 1392 | flex-grow: 1; 1393 | display: inline-block; 1394 | height: 1.25rem; 1395 | cursor: pointer; 1396 | transition: background 0.2s; 1397 | color: var(--collapse-label-fore-color); 1398 | background: var(--collapse-label-back-color); 1399 | border: 0.0714285714rem solid var(--collapse-selected-border-color); 1400 | padding: calc(1.25 * var(--universal-padding)); } 1401 | .collapse > label:hover, .collapse > label:focus { 1402 | background: var(--collapse-label-hover-back-color); } 1403 | .collapse > label + div { 1404 | flex-basis: auto; 1405 | height: 1px; 1406 | width: 1px; 1407 | margin: -1px; 1408 | overflow: hidden; 1409 | position: absolute; 1410 | clip: rect(0 0 0 0); 1411 | -webkit-clip-path: inset(100%); 1412 | clip-path: inset(100%); 1413 | transition: max-height 0.3s; 1414 | max-height: 1px; } 1415 | .collapse > :checked + label { 1416 | background: var(--collapse-selected-label-back-color); 1417 | border-color: var(--collapse-selected-label-border-color); } 1418 | .collapse > :checked + label + div { 1419 | box-sizing: border-box; 1420 | position: relative; 1421 | width: 100%; 1422 | height: auto; 1423 | overflow: auto; 1424 | margin: 0; 1425 | background: var(--collapse-content-back-color); 1426 | border: 0.0714285714rem solid var(--collapse-selected-border-color); 1427 | border-top: 0; 1428 | padding: var(--universal-padding); 1429 | clip: auto; 1430 | -webkit-clip-path: inset(0%); 1431 | clip-path: inset(0%); 1432 | max-height: 100%; } 1433 | .collapse > label:not(:first-of-type) { 1434 | border-top: 0; } 1435 | .collapse > label:first-of-type { 1436 | border-radius: var(--universal-border-radius) var(--universal-border-radius) 0 0; } 1437 | .collapse > label:last-of-type:not(:first-of-type) { 1438 | border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } 1439 | .collapse > label:last-of-type:first-of-type { 1440 | border-radius: var(--universal-border-radius); } 1441 | .collapse > :checked:last-of-type:not(:first-of-type) + label { 1442 | border-radius: 0; } 1443 | .collapse > :checked:last-of-type + label + div { 1444 | border-radius: 0 0 var(--universal-border-radius) var(--universal-border-radius); } 1445 | 1446 | /* 1447 | Custom elements for contextual background elements, toasts and tooltips. 1448 | */ 1449 | mark.tertiary { 1450 | --mark-back-color: #3cb4e6; } 1451 | 1452 | mark.tag { 1453 | padding: calc(var(--universal-padding)/2) var(--universal-padding); 1454 | border-radius: 1em; } 1455 | 1456 | /* 1457 | Definitions for progress elements and spinners. 1458 | */ 1459 | /* Progress module CSS variable definitions */ 1460 | :root { 1461 | --progress-back-color: #3cb4e6; 1462 | --progress-fore-color: #555; } 1463 | 1464 | progress { 1465 | display: block; 1466 | vertical-align: baseline; 1467 | -webkit-appearance: none; 1468 | -moz-appearance: none; 1469 | appearance: none; 1470 | height: 0.75rem; 1471 | width: calc(100% - 2 * var(--universal-margin)); 1472 | margin: var(--universal-margin); 1473 | border: 0; 1474 | border-radius: calc(2 * var(--universal-border-radius)); 1475 | background: var(--progress-back-color); 1476 | color: var(--progress-fore-color); } 1477 | progress::-webkit-progress-value { 1478 | background: var(--progress-fore-color); 1479 | border-top-left-radius: calc(2 * var(--universal-border-radius)); 1480 | border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } 1481 | progress::-webkit-progress-bar { 1482 | background: var(--progress-back-color); } 1483 | progress::-moz-progress-bar { 1484 | background: var(--progress-fore-color); 1485 | border-top-left-radius: calc(2 * var(--universal-border-radius)); 1486 | border-bottom-left-radius: calc(2 * var(--universal-border-radius)); } 1487 | progress[value="1000"]::-webkit-progress-value { 1488 | border-radius: calc(2 * var(--universal-border-radius)); } 1489 | progress[value="1000"]::-moz-progress-bar { 1490 | border-radius: calc(2 * var(--universal-border-radius)); } 1491 | progress.inline { 1492 | display: inline-block; 1493 | vertical-align: middle; 1494 | width: 60%; } 1495 | 1496 | :root { 1497 | --spinner-back-color: #ddd; 1498 | --spinner-fore-color: #555; } 1499 | 1500 | @keyframes spinner-donut-anim { 1501 | 0% { 1502 | transform: rotate(0deg); } 1503 | 100% { 1504 | transform: rotate(360deg); } } 1505 | .spinner { 1506 | display: inline-block; 1507 | margin: var(--universal-margin); 1508 | border: 0.25rem solid var(--spinner-back-color); 1509 | border-left: 0.25rem solid var(--spinner-fore-color); 1510 | border-radius: 50%; 1511 | width: 1.25rem; 1512 | height: 1.25rem; 1513 | animation: spinner-donut-anim 1.2s linear infinite; } 1514 | 1515 | /* 1516 | Custom elements for progress bars and spinners. 1517 | */ 1518 | progress.primary { 1519 | --progress-fore-color: #1976d2; } 1520 | 1521 | progress.secondary { 1522 | --progress-fore-color: #d32f2f; } 1523 | 1524 | progress.tertiary { 1525 | --progress-fore-color: #308732; } 1526 | 1527 | .spinner.primary { 1528 | --spinner-fore-color: #1976d2; } 1529 | 1530 | .spinner.secondary { 1531 | --spinner-fore-color: #d32f2f; } 1532 | 1533 | .spinner.tertiary { 1534 | --spinner-fore-color: #308732; } 1535 | 1536 | /* 1537 | Definitions for icons - powered by Feather (https://feathericons.com/). 1538 | */ 1539 | span[class^='icon-'] { 1540 | display: inline-block; 1541 | height: 1em; 1542 | width: 1em; 1543 | vertical-align: -0.125em; 1544 | background-size: contain; 1545 | margin: 0 calc(var(--universal-margin) / 4); } 1546 | span[class^='icon-'].secondary { 1547 | -webkit-filter: invert(25%); 1548 | filter: invert(25%); } 1549 | span[class^='icon-'].inverse { 1550 | -webkit-filter: invert(100%); 1551 | filter: invert(100%); } 1552 | 1553 | span.icon-alert { 1554 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='8' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='16' x2='12' y2='16'%3E%3C/line%3E%3C/svg%3E"); } 1555 | span.icon-bookmark { 1556 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z'%3E%3C/path%3E%3C/svg%3E"); } 1557 | span.icon-calendar { 1558 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='16' y1='2' x2='16' y2='6'%3E%3C/line%3E%3Cline x1='8' y1='2' x2='8' y2='6'%3E%3C/line%3E%3Cline x1='3' y1='10' x2='21' y2='10'%3E%3C/line%3E%3C/svg%3E"); } 1559 | span.icon-credit { 1560 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='1' y='4' width='22' height='16' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='1' y1='10' x2='23' y2='10'%3E%3C/line%3E%3C/svg%3E"); } 1561 | span.icon-edit { 1562 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 14.66V20a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h5.34'%3E%3C/path%3E%3Cpolygon points='18 2 22 6 12 16 8 16 8 12 18 2'%3E%3C/polygon%3E%3C/svg%3E"); } 1563 | span.icon-link { 1564 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6'%3E%3C/path%3E%3Cpolyline points='15 3 21 3 21 9'%3E%3C/polyline%3E%3Cline x1='10' y1='14' x2='21' y2='3'%3E%3C/line%3E%3C/svg%3E"); } 1565 | span.icon-help { 1566 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='17' x2='12' y2='17'%3E%3C/line%3E%3C/svg%3E"); } 1567 | span.icon-home { 1568 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z'%3E%3C/path%3E%3Cpolyline points='9 22 9 12 15 12 15 22'%3E%3C/polyline%3E%3C/svg%3E"); } 1569 | span.icon-info { 1570 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'%3E%3C/circle%3E%3Cline x1='12' y1='16' x2='12' y2='12'%3E%3C/line%3E%3Cline x1='12' y1='8' x2='12' y2='8'%3E%3C/line%3E%3C/svg%3E"); } 1571 | span.icon-lock { 1572 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='11' width='18' height='11' rx='2' ry='2'%3E%3C/rect%3E%3Cpath d='M7 11V7a5 5 0 0 1 10 0v4'%3E%3C/path%3E%3C/svg%3E"); } 1573 | span.icon-mail { 1574 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z'%3E%3C/path%3E%3Cpolyline points='22,6 12,13 2,6'%3E%3C/polyline%3E%3C/svg%3E"); } 1575 | span.icon-location { 1576 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z'%3E%3C/path%3E%3Ccircle cx='12' cy='10' r='3'%3E%3C/circle%3E%3C/svg%3E"); } 1577 | span.icon-phone { 1578 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z'%3E%3C/path%3E%3C/svg%3E"); } 1579 | span.icon-rss { 1580 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 11a9 9 0 0 1 9 9'%3E%3C/path%3E%3Cpath d='M4 4a16 16 0 0 1 16 16'%3E%3C/path%3E%3Ccircle cx='5' cy='19' r='1'%3E%3C/circle%3E%3C/svg%3E"); } 1581 | span.icon-search { 1582 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'%3E%3C/circle%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'%3E%3C/line%3E%3C/svg%3E"); } 1583 | span.icon-settings { 1584 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3Cpath d='M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z'%3E%3C/path%3E%3C/svg%3E"); } 1585 | span.icon-share { 1586 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='18' cy='5' r='3'%3E%3C/circle%3E%3Ccircle cx='6' cy='12' r='3'%3E%3C/circle%3E%3Ccircle cx='18' cy='19' r='3'%3E%3C/circle%3E%3Cline x1='8.59' y1='13.51' x2='15.42' y2='17.49'%3E%3C/line%3E%3Cline x1='15.41' y1='6.51' x2='8.59' y2='10.49'%3E%3C/line%3E%3C/svg%3E"); } 1587 | span.icon-cart { 1588 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='9' cy='21' r='1'%3E%3C/circle%3E%3Ccircle cx='20' cy='21' r='1'%3E%3C/circle%3E%3Cpath d='M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6'%3E%3C/path%3E%3C/svg%3E"); } 1589 | span.icon-upload { 1590 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'%3E%3C/path%3E%3Cpolyline points='17 8 12 3 7 8'%3E%3C/polyline%3E%3Cline x1='12' y1='3' x2='12' y2='15'%3E%3C/line%3E%3C/svg%3E"); } 1591 | span.icon-user { 1592 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%2303234b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2'%3E%3C/path%3E%3Ccircle cx='12' cy='7' r='4'%3E%3C/circle%3E%3C/svg%3E"); } 1593 | 1594 | /* 1595 | Definitions for STMicroelectronics icons (https://brandportal.st.com/document/26). 1596 | */ 1597 | span.icon-st-update { 1598 | background-image: url("Update.svg"); } 1599 | span.icon-st-add { 1600 | background-image: url("Add button.svg"); } 1601 | 1602 | /* 1603 | Definitions for utilities and helper classes. 1604 | */ 1605 | /* Utility module CSS variable definitions */ 1606 | :root { 1607 | --generic-border-color: rgba(0, 0, 0, 0.3); 1608 | --generic-box-shadow: 0 0.2857142857rem 0.2857142857rem 0 rgba(0, 0, 0, 0.125), 0 0.1428571429rem 0.1428571429rem -0.1428571429rem rgba(0, 0, 0, 0.125); } 1609 | 1610 | .hidden { 1611 | display: none !important; } 1612 | 1613 | .visually-hidden { 1614 | position: absolute !important; 1615 | width: 1px !important; 1616 | height: 1px !important; 1617 | margin: -1px !important; 1618 | border: 0 !important; 1619 | padding: 0 !important; 1620 | clip: rect(0 0 0 0) !important; 1621 | -webkit-clip-path: inset(100%) !important; 1622 | clip-path: inset(100%) !important; 1623 | overflow: hidden !important; } 1624 | 1625 | .bordered { 1626 | border: 0.0714285714rem solid var(--generic-border-color) !important; } 1627 | 1628 | .rounded { 1629 | border-radius: var(--universal-border-radius) !important; } 1630 | 1631 | .circular { 1632 | border-radius: 50% !important; } 1633 | 1634 | .shadowed { 1635 | box-shadow: var(--generic-box-shadow) !important; } 1636 | 1637 | .responsive-margin { 1638 | margin: calc(var(--universal-margin) / 4) !important; } 1639 | @media screen and (min-width: 500px) { 1640 | .responsive-margin { 1641 | margin: calc(var(--universal-margin) / 2) !important; } } 1642 | @media screen and (min-width: 1280px) { 1643 | .responsive-margin { 1644 | margin: var(--universal-margin) !important; } } 1645 | 1646 | .responsive-padding { 1647 | padding: calc(var(--universal-padding) / 4) !important; } 1648 | @media screen and (min-width: 500px) { 1649 | .responsive-padding { 1650 | padding: calc(var(--universal-padding) / 2) !important; } } 1651 | @media screen and (min-width: 1280px) { 1652 | .responsive-padding { 1653 | padding: var(--universal-padding) !important; } } 1654 | 1655 | @media screen and (max-width: 499px) { 1656 | .hidden-sm { 1657 | display: none !important; } } 1658 | @media screen and (min-width: 500px) and (max-width: 1279px) { 1659 | .hidden-md { 1660 | display: none !important; } } 1661 | @media screen and (min-width: 1280px) { 1662 | .hidden-lg { 1663 | display: none !important; } } 1664 | @media screen and (max-width: 499px) { 1665 | .visually-hidden-sm { 1666 | position: absolute !important; 1667 | width: 1px !important; 1668 | height: 1px !important; 1669 | margin: -1px !important; 1670 | border: 0 !important; 1671 | padding: 0 !important; 1672 | clip: rect(0 0 0 0) !important; 1673 | -webkit-clip-path: inset(100%) !important; 1674 | clip-path: inset(100%) !important; 1675 | overflow: hidden !important; } } 1676 | @media screen and (min-width: 500px) and (max-width: 1279px) { 1677 | .visually-hidden-md { 1678 | position: absolute !important; 1679 | width: 1px !important; 1680 | height: 1px !important; 1681 | margin: -1px !important; 1682 | border: 0 !important; 1683 | padding: 0 !important; 1684 | clip: rect(0 0 0 0) !important; 1685 | -webkit-clip-path: inset(100%) !important; 1686 | clip-path: inset(100%) !important; 1687 | overflow: hidden !important; } } 1688 | @media screen and (min-width: 1280px) { 1689 | .visually-hidden-lg { 1690 | position: absolute !important; 1691 | width: 1px !important; 1692 | height: 1px !important; 1693 | margin: -1px !important; 1694 | border: 0 !important; 1695 | padding: 0 !important; 1696 | clip: rect(0 0 0 0) !important; 1697 | -webkit-clip-path: inset(100%) !important; 1698 | clip-path: inset(100%) !important; 1699 | overflow: hidden !important; } } 1700 | 1701 | /*# sourceMappingURL=mini-custom.css.map */ 1702 | 1703 | img[alt="ST logo"] { display: block; margin: auto; width: 75%; max-width: 250px; min-width: 71px; } 1704 | img[alt="Cube logo"] { float: right; width: 30%; max-width: 10rem; min-width: 8rem; padding-right: 1rem;} 1705 | 1706 | .figure { 1707 | display: block; 1708 | margin-left: auto; 1709 | margin-right: auto; 1710 | text-align: center; 1711 | } -------------------------------------------------------------------------------- /_htmresc/st_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STMicroelectronics/stm32-ov5640/d0c3aef81cd17b3a32907a341377d2a44d95d82b/_htmresc/st_logo.png -------------------------------------------------------------------------------- /_htmresc/st_logo_2020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/STMicroelectronics/stm32-ov5640/d0c3aef81cd17b3a32907a341377d2a44d95d82b/_htmresc/st_logo_2020.png -------------------------------------------------------------------------------- /ov5640.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file ov5640.c 4 | * @author MCD Application Team 5 | * @brief This file provides the OV5640 camera driver 6 | ****************************************************************************** 7 | * @attention 8 | * 9 | * Copyright (c) 2019-2020 STMicroelectronics. 10 | * All rights reserved. 11 | * 12 | * This software is licensed under terms that can be found in the LICENSE file 13 | * in the root directory of this software component. 14 | * If no LICENSE file comes with this software, it is provided AS-IS. 15 | * 16 | ****************************************************************************** 17 | */ 18 | 19 | /* Includes ------------------------------------------------------------------*/ 20 | #include "ov5640.h" 21 | 22 | /** @addtogroup BSP 23 | * @{ 24 | */ 25 | 26 | /** @addtogroup Components 27 | * @{ 28 | */ 29 | 30 | /** @addtogroup OV5640 31 | * @brief This file provides a set of functions needed to drive the 32 | * OV5640 Camera module. 33 | * @{ 34 | */ 35 | 36 | /** @defgroup OV5640_Private_TypesDefinitions 37 | * @{ 38 | */ 39 | 40 | /** 41 | * @} 42 | */ 43 | /** @defgroup OV5640_Private_Variables 44 | * @{ 45 | */ 46 | 47 | OV5640_CAMERA_Drv_t OV5640_CAMERA_Driver = 48 | { 49 | OV5640_Init, 50 | OV5640_DeInit, 51 | OV5640_ReadID, 52 | OV5640_GetCapabilities, 53 | OV5640_SetLightMode, 54 | OV5640_SetColorEffect, 55 | OV5640_SetBrightness, 56 | OV5640_SetSaturation, 57 | OV5640_SetContrast, 58 | OV5640_SetHueDegree, 59 | OV5640_MirrorFlipConfig, 60 | OV5640_ZoomConfig, 61 | OV5640_SetResolution, 62 | OV5640_GetResolution, 63 | OV5640_SetPixelFormat, 64 | OV5640_GetPixelFormat, 65 | OV5640_NightModeConfig 66 | }; 67 | 68 | /** 69 | * @} 70 | */ 71 | 72 | /** @defgroup OV5640_Private_Functions_Prototypes Private Functions Prototypes 73 | * @{ 74 | */ 75 | static int32_t OV5640_ReadRegWrap(void *handle, uint16_t Reg, uint8_t *Data, uint16_t Length); 76 | static int32_t OV5640_WriteRegWrap(void *handle, uint16_t Reg, uint8_t *Data, uint16_t Length); 77 | static int32_t OV5640_Delay(OV5640_Object_t *pObj, uint32_t Delay); 78 | 79 | /** 80 | * @} 81 | */ 82 | 83 | /** @defgroup OV5640_Exported_Functions OV5640 Exported Functions 84 | * @{ 85 | */ 86 | /** 87 | * @brief Register component IO bus 88 | * @param Component object pointer 89 | * @retval Component status 90 | */ 91 | int32_t OV5640_RegisterBusIO(OV5640_Object_t *pObj, OV5640_IO_t *pIO) 92 | { 93 | int32_t ret; 94 | 95 | if (pObj == NULL) 96 | { 97 | ret = OV5640_ERROR; 98 | } 99 | else 100 | { 101 | pObj->IO.Init = pIO->Init; 102 | pObj->IO.DeInit = pIO->DeInit; 103 | pObj->IO.Address = pIO->Address; 104 | pObj->IO.WriteReg = pIO->WriteReg; 105 | pObj->IO.ReadReg = pIO->ReadReg; 106 | pObj->IO.GetTick = pIO->GetTick; 107 | 108 | pObj->Ctx.ReadReg = OV5640_ReadRegWrap; 109 | pObj->Ctx.WriteReg = OV5640_WriteRegWrap; 110 | pObj->Ctx.handle = pObj; 111 | 112 | if (pObj->IO.Init != NULL) 113 | { 114 | ret = pObj->IO.Init(); 115 | } 116 | else 117 | { 118 | ret = OV5640_ERROR; 119 | } 120 | } 121 | 122 | return ret; 123 | } 124 | 125 | /** 126 | * @brief Initializes the OV5640 CAMERA component. 127 | * @param pObj pointer to component object 128 | * @param Resolution Camera resolution 129 | * @param PixelFormat pixel format to be configured 130 | * @retval Component status 131 | */ 132 | int32_t OV5640_Init(OV5640_Object_t *pObj, uint32_t Resolution, uint32_t PixelFormat) 133 | { 134 | uint32_t index; 135 | int32_t ret = OV5640_OK; 136 | 137 | /* Initialization sequence for OV5640 */ 138 | static const uint16_t OV5640_Common[][2] = 139 | { 140 | {OV5640_SCCB_SYSTEM_CTRL1, 0x11}, 141 | {OV5640_SYSTEM_CTROL0, 0x82}, 142 | {OV5640_SCCB_SYSTEM_CTRL1, 0x03}, 143 | {0x3630, 0x36}, 144 | {0x3631, 0x0e}, 145 | {0x3632, 0xe2}, 146 | {0x3633, 0x12}, 147 | {0x3621, 0xe0}, 148 | {0x3704, 0xa0}, 149 | {0x3703, 0x5a}, 150 | {0x3715, 0x78}, 151 | {0x3717, 0x01}, 152 | {0x370b, 0x60}, 153 | {0x3705, 0x1a}, 154 | {0x3905, 0x02}, 155 | {0x3906, 0x10}, 156 | {0x3901, 0x0a}, 157 | {0x3731, 0x12}, 158 | {0x3600, 0x08}, 159 | {0x3601, 0x33}, 160 | {0x302d, 0x60}, 161 | {0x3620, 0x52}, 162 | {0x371b, 0x20}, 163 | {0x471c, 0x50}, 164 | {OV5640_AEC_CTRL13, 0x43}, 165 | {OV5640_AEC_GAIN_CEILING_HIGH, 0x00}, 166 | {OV5640_AEC_GAIN_CEILING_LOW, 0xf8}, 167 | {0x3635, 0x13}, 168 | {0x3636, 0x03}, 169 | {0x3634, 0x40}, 170 | {0x3622, 0x01}, 171 | {OV5640_5060HZ_CTRL01, 0x34}, 172 | {OV5640_5060HZ_CTRL04, 0x28}, 173 | {OV5640_5060HZ_CTRL05, 0x98}, 174 | {OV5640_LIGHTMETER1_TH_HIGH, 0x00}, 175 | {OV5640_LIGHTMETER1_TH_LOW, 0x00}, 176 | {OV5640_LIGHTMETER2_TH_HIGH, 0x01}, 177 | {OV5640_LIGHTMETER2_TH_LOW, 0x2c}, 178 | {OV5640_SAMPLE_NUMBER_HIGH, 0x9c}, 179 | {OV5640_SAMPLE_NUMBER_LOW, 0x40}, 180 | {OV5640_TIMING_TC_REG20, 0x06}, 181 | {OV5640_TIMING_TC_REG21, 0x00}, 182 | {OV5640_TIMING_X_INC, 0x31}, 183 | {OV5640_TIMING_Y_INC, 0x31}, 184 | {OV5640_TIMING_HS_HIGH, 0x00}, 185 | {OV5640_TIMING_HS_LOW, 0x00}, 186 | {OV5640_TIMING_VS_HIGH, 0x00}, 187 | {OV5640_TIMING_VS_LOW, 0x04}, 188 | {OV5640_TIMING_HW_HIGH, 0x0a}, 189 | {OV5640_TIMING_HW_LOW, 0x3f}, 190 | {OV5640_TIMING_VH_HIGH, 0x07}, 191 | {OV5640_TIMING_VH_LOW, 0x9b}, 192 | {OV5640_TIMING_DVPHO_HIGH, 0x03}, 193 | {OV5640_TIMING_DVPHO_LOW, 0x20}, 194 | {OV5640_TIMING_DVPVO_HIGH, 0x02}, 195 | {OV5640_TIMING_DVPVO_LOW, 0x58}, 196 | /* For 800x480 resolution: OV5640_TIMING_HTS=0x790, OV5640_TIMING_VTS=0x440 */ 197 | {OV5640_TIMING_HTS_HIGH, 0x07}, 198 | {OV5640_TIMING_HTS_LOW, 0x90}, 199 | {OV5640_TIMING_VTS_HIGH, 0x04}, 200 | {OV5640_TIMING_VTS_LOW, 0x40}, 201 | {OV5640_TIMING_HOFFSET_HIGH, 0x00}, 202 | {OV5640_TIMING_HOFFSET_LOW, 0x10}, 203 | {OV5640_TIMING_VOFFSET_HIGH, 0x00}, 204 | {OV5640_TIMING_VOFFSET_LOW, 0x06}, 205 | {0x3618, 0x00}, 206 | {0x3612, 0x29}, 207 | {0x3708, 0x64}, 208 | {0x3709, 0x52}, 209 | {0x370c, 0x03}, 210 | {OV5640_AEC_CTRL02, 0x03}, 211 | {OV5640_AEC_CTRL03, 0xd8}, 212 | {OV5640_AEC_B50_STEP_HIGH, 0x01}, 213 | {OV5640_AEC_B50_STEP_LOW, 0x27}, 214 | {OV5640_AEC_B60_STEP_HIGH, 0x00}, 215 | {OV5640_AEC_B60_STEP_LOW, 0xf6}, 216 | {OV5640_AEC_CTRL0E, 0x03}, 217 | {OV5640_AEC_CTRL0D, 0x04}, 218 | {OV5640_AEC_MAX_EXPO_HIGH, 0x03}, 219 | {OV5640_AEC_MAX_EXPO_LOW, 0xd8}, 220 | {OV5640_BLC_CTRL01, 0x02}, 221 | {OV5640_BLC_CTRL04, 0x02}, 222 | {OV5640_SYSREM_RESET00, 0x00}, 223 | {OV5640_SYSREM_RESET02, 0x1c}, 224 | {OV5640_CLOCK_ENABLE00, 0xff}, 225 | {OV5640_CLOCK_ENABLE02, 0xc3}, 226 | {OV5640_MIPI_CONTROL00, 0x58}, 227 | {0x302e, 0x00}, 228 | {OV5640_POLARITY_CTRL, 0x22}, 229 | {OV5640_FORMAT_CTRL00, 0x6F}, 230 | {OV5640_FORMAT_MUX_CTRL, 0x01}, 231 | {OV5640_JPG_MODE_SELECT, 0x03}, 232 | {OV5640_JPEG_CTRL07, 0x04}, 233 | {0x440e, 0x00}, 234 | {0x460b, 0x35}, 235 | {0x460c, 0x23}, 236 | {OV5640_PCLK_PERIOD, 0x22}, 237 | {0x3824, 0x02}, 238 | {OV5640_ISP_CONTROL00, 0xa7}, 239 | {OV5640_ISP_CONTROL01, 0xa3}, 240 | {OV5640_AWB_CTRL00, 0xff}, 241 | {OV5640_AWB_CTRL01, 0xf2}, 242 | {OV5640_AWB_CTRL02, 0x00}, 243 | {OV5640_AWB_CTRL03, 0x14}, 244 | {OV5640_AWB_CTRL04, 0x25}, 245 | {OV5640_AWB_CTRL05, 0x24}, 246 | {OV5640_AWB_CTRL06, 0x09}, 247 | {OV5640_AWB_CTRL07, 0x09}, 248 | {OV5640_AWB_CTRL08, 0x09}, 249 | {OV5640_AWB_CTRL09, 0x75}, 250 | {OV5640_AWB_CTRL10, 0x54}, 251 | {OV5640_AWB_CTRL11, 0xe0}, 252 | {OV5640_AWB_CTRL12, 0xb2}, 253 | {OV5640_AWB_CTRL13, 0x42}, 254 | {OV5640_AWB_CTRL14, 0x3d}, 255 | {OV5640_AWB_CTRL15, 0x56}, 256 | {OV5640_AWB_CTRL16, 0x46}, 257 | {OV5640_AWB_CTRL17, 0xf8}, 258 | {OV5640_AWB_CTRL18, 0x04}, 259 | {OV5640_AWB_CTRL19, 0x70}, 260 | {OV5640_AWB_CTRL20, 0xf0}, 261 | {OV5640_AWB_CTRL21, 0xf0}, 262 | {OV5640_AWB_CTRL22, 0x03}, 263 | {OV5640_AWB_CTRL23, 0x01}, 264 | {OV5640_AWB_CTRL24, 0x04}, 265 | {OV5640_AWB_CTRL25, 0x12}, 266 | {OV5640_AWB_CTRL26, 0x04}, 267 | {OV5640_AWB_CTRL27, 0x00}, 268 | {OV5640_AWB_CTRL28, 0x06}, 269 | {OV5640_AWB_CTRL29, 0x82}, 270 | {OV5640_AWB_CTRL30, 0x38}, 271 | {OV5640_CMX1, 0x1e}, 272 | {OV5640_CMX2, 0x5b}, 273 | {OV5640_CMX3, 0x08}, 274 | {OV5640_CMX4, 0x0a}, 275 | {OV5640_CMX5, 0x7e}, 276 | {OV5640_CMX6, 0x88}, 277 | {OV5640_CMX7, 0x7c}, 278 | {OV5640_CMX8, 0x6c}, 279 | {OV5640_CMX9, 0x10}, 280 | {OV5640_CMXSIGN_HIGH, 0x01}, 281 | {OV5640_CMXSIGN_LOW, 0x98}, 282 | {OV5640_CIP_SHARPENMT_TH1, 0x08}, 283 | {OV5640_CIP_SHARPENMT_TH2, 0x30}, 284 | {OV5640_CIP_SHARPENMT_OFFSET1, 0x10}, 285 | {OV5640_CIP_SHARPENMT_OFFSET2, 0x00}, 286 | {OV5640_CIP_DNS_TH1, 0x08}, 287 | {OV5640_CIP_DNS_TH2, 0x30}, 288 | {OV5640_CIP_DNS_OFFSET1, 0x08}, 289 | {OV5640_CIP_DNS_OFFSET2, 0x16}, 290 | {OV5640_CIP_CTRL, 0x08}, 291 | {OV5640_CIP_SHARPENTH_TH1, 0x30}, 292 | {OV5640_CIP_SHARPENTH_TH2, 0x04}, 293 | {OV5640_CIP_SHARPENTH_OFFSET1, 0x06}, 294 | {OV5640_GAMMA_CTRL00, 0x01}, 295 | {OV5640_GAMMA_YST00, 0x08}, 296 | {OV5640_GAMMA_YST01, 0x14}, 297 | {OV5640_GAMMA_YST02, 0x28}, 298 | {OV5640_GAMMA_YST03, 0x51}, 299 | {OV5640_GAMMA_YST04, 0x65}, 300 | {OV5640_GAMMA_YST05, 0x71}, 301 | {OV5640_GAMMA_YST06, 0x7d}, 302 | {OV5640_GAMMA_YST07, 0x87}, 303 | {OV5640_GAMMA_YST08, 0x91}, 304 | {OV5640_GAMMA_YST09, 0x9a}, 305 | {OV5640_GAMMA_YST0A, 0xaa}, 306 | {OV5640_GAMMA_YST0B, 0xb8}, 307 | {OV5640_GAMMA_YST0C, 0xcd}, 308 | {OV5640_GAMMA_YST0D, 0xdd}, 309 | {OV5640_GAMMA_YST0E, 0xea}, 310 | {OV5640_GAMMA_YST0F, 0x1d}, 311 | {OV5640_SDE_CTRL0, 0x02}, 312 | {OV5640_SDE_CTRL3, 0x40}, 313 | {OV5640_SDE_CTRL4, 0x10}, 314 | {OV5640_SDE_CTRL9, 0x10}, 315 | {OV5640_SDE_CTRL10, 0x00}, 316 | {OV5640_SDE_CTRL11, 0xf8}, 317 | {OV5640_GMTRX00, 0x23}, 318 | {OV5640_GMTRX01, 0x14}, 319 | {OV5640_GMTRX02, 0x0f}, 320 | {OV5640_GMTRX03, 0x0f}, 321 | {OV5640_GMTRX04, 0x12}, 322 | {OV5640_GMTRX05, 0x26}, 323 | {OV5640_GMTRX10, 0x0c}, 324 | {OV5640_GMTRX11, 0x08}, 325 | {OV5640_GMTRX12, 0x05}, 326 | {OV5640_GMTRX13, 0x05}, 327 | {OV5640_GMTRX14, 0x08}, 328 | {OV5640_GMTRX15, 0x0d}, 329 | {OV5640_GMTRX20, 0x08}, 330 | {OV5640_GMTRX21, 0x03}, 331 | {OV5640_GMTRX22, 0x00}, 332 | {OV5640_GMTRX23, 0x00}, 333 | {OV5640_GMTRX24, 0x03}, 334 | {OV5640_GMTRX25, 0x09}, 335 | {OV5640_GMTRX30, 0x07}, 336 | {OV5640_GMTRX31, 0x03}, 337 | {OV5640_GMTRX32, 0x00}, 338 | {OV5640_GMTRX33, 0x01}, 339 | {OV5640_GMTRX34, 0x03}, 340 | {OV5640_GMTRX35, 0x08}, 341 | {OV5640_GMTRX40, 0x0d}, 342 | {OV5640_GMTRX41, 0x08}, 343 | {OV5640_GMTRX42, 0x05}, 344 | {OV5640_GMTRX43, 0x06}, 345 | {OV5640_GMTRX44, 0x08}, 346 | {OV5640_GMTRX45, 0x0e}, 347 | {OV5640_GMTRX50, 0x29}, 348 | {OV5640_GMTRX51, 0x17}, 349 | {OV5640_GMTRX52, 0x11}, 350 | {OV5640_GMTRX53, 0x11}, 351 | {OV5640_GMTRX54, 0x15}, 352 | {OV5640_GMTRX55, 0x28}, 353 | {OV5640_BRMATRX00, 0x46}, 354 | {OV5640_BRMATRX01, 0x26}, 355 | {OV5640_BRMATRX02, 0x08}, 356 | {OV5640_BRMATRX03, 0x26}, 357 | {OV5640_BRMATRX04, 0x64}, 358 | {OV5640_BRMATRX05, 0x26}, 359 | {OV5640_BRMATRX06, 0x24}, 360 | {OV5640_BRMATRX07, 0x22}, 361 | {OV5640_BRMATRX08, 0x24}, 362 | {OV5640_BRMATRX09, 0x24}, 363 | {OV5640_BRMATRX20, 0x06}, 364 | {OV5640_BRMATRX21, 0x22}, 365 | {OV5640_BRMATRX22, 0x40}, 366 | {OV5640_BRMATRX23, 0x42}, 367 | {OV5640_BRMATRX24, 0x24}, 368 | {OV5640_BRMATRX30, 0x26}, 369 | {OV5640_BRMATRX31, 0x24}, 370 | {OV5640_BRMATRX32, 0x22}, 371 | {OV5640_BRMATRX33, 0x22}, 372 | {OV5640_BRMATRX34, 0x26}, 373 | {OV5640_BRMATRX40, 0x44}, 374 | {OV5640_BRMATRX41, 0x24}, 375 | {OV5640_BRMATRX42, 0x26}, 376 | {OV5640_BRMATRX43, 0x28}, 377 | {OV5640_BRMATRX44, 0x42}, 378 | {OV5640_LENC_BR_OFFSET, 0xce}, 379 | {0x5025, 0x00}, 380 | {OV5640_AEC_CTRL0F, 0x30}, 381 | {OV5640_AEC_CTRL10, 0x28}, 382 | {OV5640_AEC_CTRL1B, 0x30}, 383 | {OV5640_AEC_CTRL1E, 0x26}, 384 | {OV5640_AEC_CTRL11, 0x60}, 385 | {OV5640_AEC_CTRL1F, 0x14}, 386 | {OV5640_SYSTEM_CTROL0, 0x02}, 387 | }; 388 | uint8_t tmp; 389 | 390 | if (pObj->IsInitialized == 0U) 391 | { 392 | /* Check if resolution is supported */ 393 | if ((Resolution > OV5640_R800x480) || 394 | ((PixelFormat != OV5640_RGB565) && (PixelFormat != OV5640_YUV422) && 395 | (PixelFormat != OV5640_RGB888) && (PixelFormat != OV5640_Y8) && 396 | (PixelFormat != OV5640_JPEG))) 397 | { 398 | ret = OV5640_ERROR; 399 | } 400 | else 401 | { 402 | /* Set common parameters for all resolutions */ 403 | for (index = 0; index < (sizeof(OV5640_Common) / 4U) ; index++) 404 | { 405 | if (ret != OV5640_ERROR) 406 | { 407 | tmp = (uint8_t)OV5640_Common[index][1]; 408 | 409 | if (ov5640_write_reg(&pObj->Ctx, OV5640_Common[index][0], &tmp, 1) != OV5640_OK) 410 | { 411 | ret = OV5640_ERROR; 412 | } 413 | } 414 | } 415 | 416 | if(ret == OV5640_OK) 417 | { 418 | /* Set configuration for Serial Interface */ 419 | if(pObj->Mode == SERIAL_MODE) 420 | { 421 | if(OV5640_EnableMIPIMode(pObj) != OV5640_OK) 422 | { 423 | ret = OV5640_ERROR; 424 | } 425 | else if(OV5640_SetMIPIVirtualChannel(pObj, pObj->VirtualChannelID) != OV5640_OK) 426 | { 427 | ret = OV5640_ERROR; 428 | } 429 | } 430 | else 431 | { 432 | /* Set configuration for parallel Interface */ 433 | if(OV5640_EnableDVPMode(pObj) != OV5640_OK) 434 | { 435 | ret = OV5640_ERROR; 436 | } 437 | else 438 | { 439 | ret = OV5640_OK; 440 | } 441 | } 442 | } 443 | 444 | 445 | if (ret == OV5640_OK) 446 | { 447 | /* Set specific parameters for each resolution */ 448 | if (OV5640_SetResolution(pObj, Resolution) != OV5640_OK) 449 | { 450 | ret = OV5640_ERROR; 451 | }/* Set specific parameters for each pixel format */ 452 | else if (OV5640_SetPixelFormat(pObj, PixelFormat) != OV5640_OK) 453 | { 454 | ret = OV5640_ERROR; 455 | }/* Set PixelClock, Href and VSync Polarity */ 456 | else if (OV5640_SetPolarities(pObj, OV5640_POLARITY_PCLK_HIGH, OV5640_POLARITY_HREF_HIGH, 457 | OV5640_POLARITY_VSYNC_HIGH) != OV5640_OK) 458 | { 459 | ret = OV5640_ERROR; 460 | } 461 | else 462 | { 463 | pObj->IsInitialized = 1U; 464 | } 465 | } 466 | } 467 | } 468 | 469 | return ret; 470 | } 471 | 472 | /** 473 | * @brief De-initializes the camera sensor. 474 | * @param pObj pointer to component object 475 | * @retval Component status 476 | */ 477 | int32_t OV5640_DeInit(OV5640_Object_t *pObj) 478 | { 479 | if (pObj->IsInitialized == 1U) 480 | { 481 | /* De-initialize camera sensor interface */ 482 | pObj->IsInitialized = 0U; 483 | } 484 | 485 | return OV5640_OK; 486 | } 487 | 488 | /** 489 | * @brief Set OV5640 camera Pixel Format. 490 | * @param pObj pointer to component object 491 | * @param PixelFormat pixel format to be configured 492 | * @retval Component status 493 | */ 494 | int32_t OV5640_SetPixelFormat(OV5640_Object_t *pObj, uint32_t PixelFormat) 495 | { 496 | int32_t ret = OV5640_OK; 497 | uint32_t index; 498 | uint8_t tmp; 499 | 500 | /* Initialization sequence for RGB565 pixel format */ 501 | static const uint16_t OV5640_PF_RGB565[][2] = 502 | { 503 | /* SET PIXEL FORMAT: RGB565 */ 504 | {OV5640_FORMAT_CTRL00, 0x6F}, 505 | {OV5640_FORMAT_MUX_CTRL, 0x01}, 506 | }; 507 | 508 | /* Initialization sequence for YUV422 pixel format */ 509 | static const uint16_t OV5640_PF_YUV422[][2] = 510 | { 511 | /* SET PIXEL FORMAT: YUV422 */ 512 | {OV5640_FORMAT_CTRL00, 0x30}, 513 | {OV5640_FORMAT_MUX_CTRL, 0x00}, 514 | }; 515 | 516 | /* Initialization sequence for RGB888 pixel format */ 517 | static const uint16_t OV5640_PF_RGB888[][2] = 518 | { 519 | /* SET PIXEL FORMAT: RGB888 (RGBRGB)*/ 520 | {OV5640_FORMAT_CTRL00, 0x23}, 521 | {OV5640_FORMAT_MUX_CTRL, 0x01}, 522 | }; 523 | 524 | /* Initialization sequence for Monochrome 8bits pixel format */ 525 | static const uint16_t OV5640_PF_Y8[][2] = 526 | { 527 | /* SET PIXEL FORMAT: Y 8bits */ 528 | {OV5640_FORMAT_CTRL00, 0x10}, 529 | {OV5640_FORMAT_MUX_CTRL, 0x00}, 530 | }; 531 | 532 | /* Initialization sequence for JPEG format */ 533 | static const uint16_t OV5640_PF_JPEG[][2] = 534 | { 535 | /* SET PIXEL FORMAT: JPEG */ 536 | {OV5640_FORMAT_CTRL00, 0x30}, 537 | {OV5640_FORMAT_MUX_CTRL, 0x00}, 538 | }; 539 | 540 | /* Check if PixelFormat is supported */ 541 | if ((PixelFormat != OV5640_RGB565) && (PixelFormat != OV5640_YUV422) && 542 | (PixelFormat != OV5640_RGB888) && (PixelFormat != OV5640_Y8) && 543 | (PixelFormat != OV5640_JPEG)) 544 | { 545 | /* Pixel format not supported */ 546 | ret = OV5640_ERROR; 547 | } 548 | else 549 | { 550 | /* Set specific parameters for each PixelFormat */ 551 | switch (PixelFormat) 552 | { 553 | case OV5640_YUV422: 554 | for (index = 0; index < (sizeof(OV5640_PF_YUV422) / 4U); index++) 555 | { 556 | if (ret != OV5640_ERROR) 557 | { 558 | tmp = (uint8_t)OV5640_PF_YUV422[index][1]; 559 | if (ov5640_write_reg(&pObj->Ctx, OV5640_PF_YUV422[index][0], &tmp, 1) != OV5640_OK) 560 | { 561 | ret = OV5640_ERROR; 562 | } 563 | else 564 | { 565 | (void)OV5640_Delay(pObj, 1); 566 | } 567 | } 568 | } 569 | break; 570 | 571 | case OV5640_RGB888: 572 | for (index = 0; index < (sizeof(OV5640_PF_RGB888) / 4U); index++) 573 | { 574 | if (ret != OV5640_ERROR) 575 | { 576 | tmp = (uint8_t)OV5640_PF_RGB888[index][1]; 577 | if (ov5640_write_reg(&pObj->Ctx, OV5640_PF_RGB888[index][0], &tmp, 1) != OV5640_OK) 578 | { 579 | ret = OV5640_ERROR; 580 | } 581 | else 582 | { 583 | (void)OV5640_Delay(pObj, 1); 584 | } 585 | } 586 | } 587 | break; 588 | 589 | case OV5640_Y8: 590 | for (index = 0; index < (sizeof(OV5640_PF_Y8) / 4U); index++) 591 | { 592 | if (ret != OV5640_ERROR) 593 | { 594 | tmp = (uint8_t)OV5640_PF_Y8[index][1]; 595 | if (ov5640_write_reg(&pObj->Ctx, OV5640_PF_Y8[index][0], &tmp, 1) != OV5640_OK) 596 | { 597 | ret = OV5640_ERROR; 598 | } 599 | else 600 | { 601 | (void)OV5640_Delay(pObj, 1); 602 | } 603 | } 604 | } 605 | break; 606 | 607 | case OV5640_JPEG: 608 | for (index = 0; index < (sizeof(OV5640_PF_JPEG) / 4U); index++) 609 | { 610 | if (ret != OV5640_ERROR) 611 | { 612 | tmp = (uint8_t)OV5640_PF_JPEG[index][1]; 613 | if (ov5640_write_reg(&pObj->Ctx, OV5640_PF_JPEG[index][0], &tmp, 1) != OV5640_OK) 614 | { 615 | ret = OV5640_ERROR; 616 | } 617 | else 618 | { 619 | (void)OV5640_Delay(pObj, 1); 620 | } 621 | } 622 | } 623 | break; 624 | 625 | case OV5640_RGB565: 626 | default: 627 | for (index = 0; index < (sizeof(OV5640_PF_RGB565) / 4U); index++) 628 | { 629 | if (ret != OV5640_ERROR) 630 | { 631 | tmp = (uint8_t)OV5640_PF_RGB565[index][1]; 632 | if (ov5640_write_reg(&pObj->Ctx, OV5640_PF_RGB565[index][0], &tmp, 1) != OV5640_OK) 633 | { 634 | ret = OV5640_ERROR; 635 | } 636 | else 637 | { 638 | (void)OV5640_Delay(pObj, 1); 639 | } 640 | } 641 | } 642 | break; 643 | 644 | } 645 | 646 | if (PixelFormat == OV5640_JPEG) 647 | { 648 | if (ov5640_read_reg(&pObj->Ctx, OV5640_TIMING_TC_REG21, &tmp, 1) != OV5640_OK) 649 | { 650 | ret = OV5640_ERROR; 651 | } 652 | else 653 | { 654 | tmp |= (1 << 5); 655 | if (ov5640_write_reg(&pObj->Ctx, OV5640_TIMING_TC_REG21, &tmp, 1) != OV5640_OK) 656 | { 657 | ret = OV5640_ERROR; 658 | } 659 | else 660 | { 661 | if (ov5640_read_reg(&pObj->Ctx, OV5640_SYSREM_RESET02, &tmp, 1) != OV5640_OK) 662 | { 663 | ret = OV5640_ERROR; 664 | } 665 | else 666 | { 667 | tmp &= ~((1 << 4) | (1 << 3) | (1 << 2)); 668 | if (ov5640_write_reg(&pObj->Ctx, OV5640_SYSREM_RESET02, &tmp, 1) != OV5640_OK) 669 | { 670 | ret = OV5640_ERROR; 671 | } 672 | else 673 | { 674 | if (ov5640_read_reg(&pObj->Ctx, OV5640_CLOCK_ENABLE02, &tmp, 1) != OV5640_OK) 675 | { 676 | ret = OV5640_ERROR; 677 | } 678 | else 679 | { 680 | tmp |= ((1 << 5) | (1 << 3)); 681 | if (ov5640_write_reg(&pObj->Ctx, OV5640_CLOCK_ENABLE02, &tmp, 1) != OV5640_OK) 682 | { 683 | ret = OV5640_ERROR; 684 | } 685 | } 686 | } 687 | } 688 | } 689 | } 690 | } 691 | } 692 | return ret; 693 | } 694 | 695 | /** 696 | * @brief Set OV5640 camera Pixel Format. 697 | * @param pObj pointer to component object 698 | * @param PixelFormat pixel format to be configured 699 | * @retval Component status 700 | */ 701 | int32_t OV5640_GetPixelFormat(OV5640_Object_t *pObj, uint32_t *PixelFormat) 702 | { 703 | (void)(pObj); 704 | (void)(PixelFormat); 705 | 706 | return OV5640_ERROR; 707 | } 708 | 709 | /** 710 | * @brief Get OV5640 camera resolution. 711 | * @param pObj pointer to component object 712 | * @param Resolution Camera resolution 713 | * @retval Component status 714 | */ 715 | int32_t OV5640_SetResolution(OV5640_Object_t *pObj, uint32_t Resolution) 716 | { 717 | int32_t ret = OV5640_OK; 718 | uint32_t index; 719 | uint8_t tmp; 720 | 721 | /* Initialization sequence for WVGA resolution (800x480)*/ 722 | static const uint16_t OV5640_WVGA[][2] = 723 | { 724 | {OV5640_TIMING_DVPHO_HIGH, 0x03}, 725 | {OV5640_TIMING_DVPHO_LOW, 0x20}, 726 | {OV5640_TIMING_DVPVO_HIGH, 0x01}, 727 | {OV5640_TIMING_DVPVO_LOW, 0xE0}, 728 | }; 729 | 730 | /* Initialization sequence for VGA resolution (640x480)*/ 731 | static const uint16_t OV5640_VGA[][2] = 732 | { 733 | {OV5640_TIMING_DVPHO_HIGH, 0x02}, 734 | {OV5640_TIMING_DVPHO_LOW, 0x80}, 735 | {OV5640_TIMING_DVPVO_HIGH, 0x01}, 736 | {OV5640_TIMING_DVPVO_LOW, 0xE0}, 737 | }; 738 | 739 | /* Initialization sequence for 480x272 resolution */ 740 | static const uint16_t OV5640_480x272[][2] = 741 | { 742 | {OV5640_TIMING_DVPHO_HIGH, 0x01}, 743 | {OV5640_TIMING_DVPHO_LOW, 0xE0}, 744 | {OV5640_TIMING_DVPVO_HIGH, 0x01}, 745 | {OV5640_TIMING_DVPVO_LOW, 0x10}, 746 | }; 747 | 748 | /* Initialization sequence for QVGA resolution (320x240) */ 749 | static const uint16_t OV5640_QVGA[][2] = 750 | { 751 | {OV5640_TIMING_DVPHO_HIGH, 0x01}, 752 | {OV5640_TIMING_DVPHO_LOW, 0x40}, 753 | {OV5640_TIMING_DVPVO_HIGH, 0x00}, 754 | {OV5640_TIMING_DVPVO_LOW, 0xF0}, 755 | }; 756 | 757 | /* Initialization sequence for QQVGA resolution (160x120) */ 758 | static const uint16_t OV5640_QQVGA[][2] = 759 | { 760 | {OV5640_TIMING_DVPHO_HIGH, 0x00}, 761 | {OV5640_TIMING_DVPHO_LOW, 0xA0}, 762 | {OV5640_TIMING_DVPVO_HIGH, 0x00}, 763 | {OV5640_TIMING_DVPVO_LOW, 0x78}, 764 | }; 765 | 766 | /* Check if resolution is supported */ 767 | if (Resolution > OV5640_R800x480) 768 | { 769 | ret = OV5640_ERROR; 770 | } 771 | else 772 | { 773 | /* Initialize OV5640 */ 774 | switch (Resolution) 775 | { 776 | case OV5640_R160x120: 777 | for (index = 0; index < (sizeof(OV5640_QQVGA) / 4U); index++) 778 | { 779 | if (ret != OV5640_ERROR) 780 | { 781 | tmp = (uint8_t)OV5640_QQVGA[index][1]; 782 | if (ov5640_write_reg(&pObj->Ctx, OV5640_QQVGA[index][0], &tmp, 1) != OV5640_OK) 783 | { 784 | ret = OV5640_ERROR; 785 | } 786 | } 787 | } 788 | break; 789 | case OV5640_R320x240: 790 | for (index = 0; index < (sizeof(OV5640_QVGA) / 4U); index++) 791 | { 792 | if (ret != OV5640_ERROR) 793 | { 794 | tmp = (uint8_t)OV5640_QVGA[index][1]; 795 | if (ov5640_write_reg(&pObj->Ctx, OV5640_QVGA[index][0], &tmp, 1) != OV5640_OK) 796 | { 797 | ret = OV5640_ERROR; 798 | } 799 | } 800 | } 801 | break; 802 | case OV5640_R480x272: 803 | for (index = 0; index < (sizeof(OV5640_480x272) / 4U); index++) 804 | { 805 | if (ret != OV5640_ERROR) 806 | { 807 | tmp = (uint8_t)OV5640_480x272[index][1]; 808 | if (ov5640_write_reg(&pObj->Ctx, OV5640_480x272[index][0], &tmp, 1) != OV5640_OK) 809 | { 810 | ret = OV5640_ERROR; 811 | } 812 | } 813 | } 814 | break; 815 | case OV5640_R640x480: 816 | for (index = 0; index < (sizeof(OV5640_VGA) / 4U); index++) 817 | { 818 | if (ret != OV5640_ERROR) 819 | { 820 | tmp = (uint8_t)OV5640_VGA[index][1]; 821 | if (ov5640_write_reg(&pObj->Ctx, OV5640_VGA[index][0], &tmp, 1) != OV5640_OK) 822 | { 823 | ret = OV5640_ERROR; 824 | } 825 | } 826 | } 827 | break; 828 | case OV5640_R800x480: 829 | for (index = 0; index < (sizeof(OV5640_WVGA) / 4U); index++) 830 | { 831 | if (ret != OV5640_ERROR) 832 | { 833 | tmp = (uint8_t)OV5640_WVGA[index][1]; 834 | if (ov5640_write_reg(&pObj->Ctx, OV5640_WVGA[index][0], &tmp, 1) != OV5640_OK) 835 | { 836 | ret = OV5640_ERROR; 837 | } 838 | } 839 | } 840 | break; 841 | default: 842 | ret = OV5640_ERROR; 843 | break; 844 | } 845 | } 846 | 847 | return ret; 848 | } 849 | 850 | /** 851 | * @brief Get OV5640 camera resolution. 852 | * @param pObj pointer to component object 853 | * @param Resolution Camera resolution 854 | * @retval Component status 855 | */ 856 | int32_t OV5640_GetResolution(OV5640_Object_t *pObj, uint32_t *Resolution) 857 | { 858 | int32_t ret; 859 | uint16_t x_size; 860 | uint16_t y_size; 861 | uint8_t tmp; 862 | 863 | if (ov5640_read_reg(&pObj->Ctx, OV5640_TIMING_DVPHO_HIGH, &tmp, 1) != OV5640_OK) 864 | { 865 | ret = OV5640_ERROR; 866 | } 867 | else 868 | { 869 | x_size = (uint16_t)tmp << 8U; 870 | 871 | if (ov5640_read_reg(&pObj->Ctx, OV5640_TIMING_DVPHO_LOW, &tmp, 1) != OV5640_OK) 872 | { 873 | ret = OV5640_ERROR; 874 | } 875 | else 876 | { 877 | x_size |= tmp; 878 | 879 | if (ov5640_read_reg(&pObj->Ctx, OV5640_TIMING_DVPVO_HIGH, &tmp, 1) != OV5640_OK) 880 | { 881 | ret = OV5640_ERROR; 882 | } 883 | else 884 | { 885 | y_size = (uint16_t)tmp << 8U; 886 | if (ov5640_read_reg(&pObj->Ctx, OV5640_TIMING_DVPVO_LOW, &tmp, 1) != OV5640_OK) 887 | { 888 | ret = OV5640_ERROR; 889 | } 890 | else 891 | { 892 | y_size |= tmp; 893 | 894 | if ((x_size == 800U) && (y_size == 480U)) 895 | { 896 | *Resolution = OV5640_R800x480; 897 | ret = OV5640_OK; 898 | } 899 | else if ((x_size == 640U) && (y_size == 480U)) 900 | { 901 | *Resolution = OV5640_R640x480; 902 | ret = OV5640_OK; 903 | } 904 | else if ((x_size == 480U) && (y_size == 272U)) 905 | { 906 | *Resolution = OV5640_R480x272; 907 | ret = OV5640_OK; 908 | } 909 | else if ((x_size == 320U) && (y_size == 240U)) 910 | { 911 | *Resolution = OV5640_R320x240; 912 | ret = OV5640_OK; 913 | } 914 | else if ((x_size == 160U) && (y_size == 120U)) 915 | { 916 | *Resolution = OV5640_R160x120; 917 | ret = OV5640_OK; 918 | } 919 | else 920 | { 921 | ret = OV5640_ERROR; 922 | } 923 | } 924 | } 925 | } 926 | } 927 | 928 | return ret; 929 | } 930 | 931 | /** 932 | * @brief Set OV5640 camera PCLK, HREF and VSYNC Polarities 933 | * @param pObj pointer to component object 934 | * @param PclkPolarity Polarity of the PixelClock 935 | * @param HrefPolarity Polarity of the Href 936 | * @param VsyncPolarity Polarity of the Vsync 937 | * @retval Component status 938 | */ 939 | int32_t OV5640_SetPolarities(OV5640_Object_t *pObj, uint32_t PclkPolarity, uint32_t HrefPolarity, 940 | uint32_t VsyncPolarity) 941 | { 942 | uint8_t tmp; 943 | int32_t ret = OV5640_OK; 944 | 945 | if ((pObj == NULL) || ((PclkPolarity != OV5640_POLARITY_PCLK_LOW) && (PclkPolarity != OV5640_POLARITY_PCLK_HIGH)) || 946 | ((HrefPolarity != OV5640_POLARITY_HREF_LOW) && (HrefPolarity != OV5640_POLARITY_HREF_HIGH)) || 947 | ((VsyncPolarity != OV5640_POLARITY_VSYNC_LOW) && (VsyncPolarity != OV5640_POLARITY_VSYNC_HIGH))) 948 | { 949 | ret = OV5640_ERROR; 950 | } 951 | else 952 | { 953 | tmp = (uint8_t)(PclkPolarity << 5U) | (HrefPolarity << 1U) | VsyncPolarity; 954 | 955 | if (ov5640_write_reg(&pObj->Ctx, OV5640_POLARITY_CTRL, &tmp, 1) != OV5640_OK) 956 | { 957 | ret = OV5640_ERROR; 958 | } 959 | } 960 | 961 | return ret; 962 | } 963 | 964 | /** 965 | * @brief get OV5640 camera PCLK, HREF and VSYNC Polarities 966 | * @param pObj pointer to component object 967 | * @param PclkPolarity Polarity of the PixelClock 968 | * @param HrefPolarity Polarity of the Href 969 | * @param VsyncPolarity Polarity of the Vsync 970 | * @retval Component status 971 | */ 972 | int32_t OV5640_GetPolarities(OV5640_Object_t *pObj, uint32_t *PclkPolarity, uint32_t *HrefPolarity, 973 | uint32_t *VsyncPolarity) 974 | { 975 | uint8_t tmp; 976 | int32_t ret = OV5640_OK; 977 | 978 | if ((pObj == NULL) || (PclkPolarity == NULL) || (HrefPolarity == NULL) || (VsyncPolarity == NULL)) 979 | { 980 | ret = OV5640_ERROR; 981 | } 982 | else if (ov5640_read_reg(&pObj->Ctx, OV5640_POLARITY_CTRL, &tmp, 1) != OV5640_OK) 983 | { 984 | ret = OV5640_ERROR; 985 | } 986 | else 987 | { 988 | *PclkPolarity = (tmp >> 5U) & 0x01U; 989 | *HrefPolarity = (tmp >> 1U) & 0x01U; 990 | *VsyncPolarity = tmp & 0x01; 991 | } 992 | 993 | return ret; 994 | } 995 | 996 | /** 997 | * @brief Read the OV5640 Camera identity. 998 | * @param pObj pointer to component object 999 | * @param Id pointer to component ID 1000 | * @retval Component status 1001 | */ 1002 | int32_t OV5640_ReadID(OV5640_Object_t *pObj, uint32_t *Id) 1003 | { 1004 | int32_t ret; 1005 | uint8_t tmp; 1006 | 1007 | /* Initialize I2C */ 1008 | pObj->IO.Init(); 1009 | 1010 | /* Prepare the camera to be configured */ 1011 | tmp = 0x80; 1012 | if (ov5640_write_reg(&pObj->Ctx, OV5640_SYSTEM_CTROL0, &tmp, 1) != OV5640_OK) 1013 | { 1014 | ret = OV5640_ERROR; 1015 | } 1016 | else 1017 | { 1018 | (void)OV5640_Delay(pObj, 500); 1019 | 1020 | if (ov5640_read_reg(&pObj->Ctx, OV5640_CHIP_ID_HIGH_BYTE, &tmp, 1) != OV5640_OK) 1021 | { 1022 | ret = OV5640_ERROR; 1023 | } 1024 | else 1025 | { 1026 | *Id = (uint32_t)tmp << 8U; 1027 | if (ov5640_read_reg(&pObj->Ctx, OV5640_CHIP_ID_LOW_BYTE, &tmp, 1) != OV5640_OK) 1028 | { 1029 | ret = OV5640_ERROR; 1030 | } 1031 | else 1032 | { 1033 | *Id |= tmp; 1034 | ret = OV5640_OK; 1035 | } 1036 | } 1037 | } 1038 | 1039 | /* Component status */ 1040 | return ret; 1041 | } 1042 | 1043 | /** 1044 | * @brief Read the OV5640 Camera Capabilities. 1045 | * @param pObj pointer to component object 1046 | * @param Capabilities pointer to component Capabilities 1047 | * @retval Component status 1048 | */ 1049 | int32_t OV5640_GetCapabilities(OV5640_Object_t *pObj, OV5640_Capabilities_t *Capabilities) 1050 | { 1051 | int32_t ret; 1052 | 1053 | if (pObj == NULL) 1054 | { 1055 | ret = OV5640_ERROR; 1056 | } 1057 | else 1058 | { 1059 | Capabilities->Config_Brightness = 1; 1060 | Capabilities->Config_Contrast = 1; 1061 | Capabilities->Config_HueDegree = 1; 1062 | Capabilities->Config_LightMode = 1; 1063 | Capabilities->Config_MirrorFlip = 1; 1064 | Capabilities->Config_NightMode = 1; 1065 | Capabilities->Config_Resolution = 1; 1066 | Capabilities->Config_Saturation = 1; 1067 | Capabilities->Config_SpecialEffect = 1; 1068 | Capabilities->Config_Zoom = 1; 1069 | 1070 | ret = OV5640_OK; 1071 | } 1072 | 1073 | return ret; 1074 | } 1075 | 1076 | /** 1077 | * @brief Set the OV5640 camera Light Mode. 1078 | * @param pObj pointer to component object 1079 | * @param Effect Effect to be configured 1080 | * @retval Component status 1081 | */ 1082 | int32_t OV5640_SetLightMode(OV5640_Object_t *pObj, uint32_t LightMode) 1083 | { 1084 | int32_t ret; 1085 | uint32_t index; 1086 | uint8_t tmp; 1087 | 1088 | /* OV5640 Light Mode setting */ 1089 | static const uint16_t OV5640_LightModeAuto[][2] = 1090 | { 1091 | {OV5640_AWB_MANUAL_CONTROL, 0x00}, 1092 | {OV5640_AWB_R_GAIN_MSB, 0x04}, 1093 | {OV5640_AWB_R_GAIN_LSB, 0x00}, 1094 | {OV5640_AWB_G_GAIN_MSB, 0x04}, 1095 | {OV5640_AWB_G_GAIN_LSB, 0x00}, 1096 | {OV5640_AWB_B_GAIN_MSB, 0x04}, 1097 | {OV5640_AWB_B_GAIN_LSB, 0x00}, 1098 | }; 1099 | 1100 | static const uint16_t OV5640_LightModeCloudy[][2] = 1101 | { 1102 | {OV5640_AWB_MANUAL_CONTROL, 0x01}, 1103 | {OV5640_AWB_R_GAIN_MSB, 0x06}, 1104 | {OV5640_AWB_R_GAIN_LSB, 0x48}, 1105 | {OV5640_AWB_G_GAIN_MSB, 0x04}, 1106 | {OV5640_AWB_G_GAIN_LSB, 0x00}, 1107 | {OV5640_AWB_B_GAIN_MSB, 0x04}, 1108 | {OV5640_AWB_B_GAIN_LSB, 0xD3}, 1109 | }; 1110 | 1111 | static const uint16_t OV5640_LightModeOffice[][2] = 1112 | { 1113 | {OV5640_AWB_MANUAL_CONTROL, 0x01}, 1114 | {OV5640_AWB_R_GAIN_MSB, 0x05}, 1115 | {OV5640_AWB_R_GAIN_LSB, 0x48}, 1116 | {OV5640_AWB_G_GAIN_MSB, 0x04}, 1117 | {OV5640_AWB_G_GAIN_LSB, 0x00}, 1118 | {OV5640_AWB_B_GAIN_MSB, 0x07}, 1119 | {OV5640_AWB_B_GAIN_LSB, 0xCF}, 1120 | }; 1121 | 1122 | static const uint16_t OV5640_LightModeHome[][2] = 1123 | { 1124 | {OV5640_AWB_MANUAL_CONTROL, 0x01}, 1125 | {OV5640_AWB_R_GAIN_MSB, 0x04}, 1126 | {OV5640_AWB_R_GAIN_LSB, 0x10}, 1127 | {OV5640_AWB_G_GAIN_MSB, 0x04}, 1128 | {OV5640_AWB_G_GAIN_LSB, 0x00}, 1129 | {OV5640_AWB_B_GAIN_MSB, 0x08}, 1130 | {OV5640_AWB_B_GAIN_LSB, 0xB6}, 1131 | }; 1132 | 1133 | static const uint16_t OV5640_LightModeSunny[][2] = 1134 | { 1135 | {OV5640_AWB_MANUAL_CONTROL, 0x01}, 1136 | {OV5640_AWB_R_GAIN_MSB, 0x06}, 1137 | {OV5640_AWB_R_GAIN_LSB, 0x1C}, 1138 | {OV5640_AWB_G_GAIN_MSB, 0x04}, 1139 | {OV5640_AWB_G_GAIN_LSB, 0x00}, 1140 | {OV5640_AWB_B_GAIN_MSB, 0x04}, 1141 | {OV5640_AWB_B_GAIN_LSB, 0xF3}, 1142 | }; 1143 | 1144 | tmp = 0x00; 1145 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AWB_MANUAL_CONTROL, &tmp, 1); 1146 | if (ret == OV5640_OK) 1147 | { 1148 | tmp = 0x46; 1149 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AWB_CTRL16, &tmp, 1); 1150 | } 1151 | 1152 | if (ret == OV5640_OK) 1153 | { 1154 | tmp = 0xF8; 1155 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AWB_CTRL17, &tmp, 1); 1156 | } 1157 | 1158 | if (ret == OV5640_OK) 1159 | { 1160 | tmp = 0x04; 1161 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AWB_CTRL18, &tmp, 1); 1162 | } 1163 | 1164 | if (ret == OV5640_OK) 1165 | { 1166 | switch (LightMode) 1167 | { 1168 | case OV5640_LIGHT_SUNNY: 1169 | for (index = 0; index < (sizeof(OV5640_LightModeSunny) / 4U) ; index++) 1170 | { 1171 | if (ret != OV5640_ERROR) 1172 | { 1173 | tmp = (uint8_t)OV5640_LightModeSunny[index][1]; 1174 | if (ov5640_write_reg(&pObj->Ctx, OV5640_LightModeSunny[index][0], &tmp, 1) != OV5640_OK) 1175 | { 1176 | ret = OV5640_ERROR; 1177 | } 1178 | } 1179 | } 1180 | break; 1181 | case OV5640_LIGHT_OFFICE: 1182 | for (index = 0; index < (sizeof(OV5640_LightModeOffice) / 4U) ; index++) 1183 | { 1184 | if (ret != OV5640_ERROR) 1185 | { 1186 | tmp = (uint8_t)OV5640_LightModeOffice[index][1]; 1187 | if (ov5640_write_reg(&pObj->Ctx, OV5640_LightModeOffice[index][0], &tmp, 1) != OV5640_OK) 1188 | { 1189 | ret = OV5640_ERROR; 1190 | } 1191 | } 1192 | } 1193 | break; 1194 | case OV5640_LIGHT_CLOUDY: 1195 | for (index = 0; index < (sizeof(OV5640_LightModeCloudy) / 4U) ; index++) 1196 | { 1197 | if (ret != OV5640_ERROR) 1198 | { 1199 | tmp = (uint8_t)OV5640_LightModeCloudy[index][1]; 1200 | if (ov5640_write_reg(&pObj->Ctx, OV5640_LightModeCloudy[index][0], &tmp, 1) != OV5640_OK) 1201 | { 1202 | ret = OV5640_ERROR; 1203 | } 1204 | } 1205 | } 1206 | break; 1207 | case OV5640_LIGHT_HOME: 1208 | for (index = 0; index < (sizeof(OV5640_LightModeHome) / 4U) ; index++) 1209 | { 1210 | if (ret != OV5640_ERROR) 1211 | { 1212 | tmp = (uint8_t)OV5640_LightModeHome[index][1]; 1213 | if (ov5640_write_reg(&pObj->Ctx, OV5640_LightModeHome[index][0], &tmp, 1) != OV5640_OK) 1214 | { 1215 | ret = OV5640_ERROR; 1216 | } 1217 | } 1218 | } 1219 | break; 1220 | case OV5640_LIGHT_AUTO: 1221 | default : 1222 | for (index = 0; index < (sizeof(OV5640_LightModeAuto) / 4U) ; index++) 1223 | { 1224 | if (ret != OV5640_ERROR) 1225 | { 1226 | tmp = (uint8_t)OV5640_LightModeAuto[index][1]; 1227 | if (ov5640_write_reg(&pObj->Ctx, OV5640_LightModeAuto[index][0], &tmp, 1) != OV5640_OK) 1228 | { 1229 | ret = OV5640_ERROR; 1230 | } 1231 | } 1232 | } 1233 | break; 1234 | } 1235 | } 1236 | return ret; 1237 | } 1238 | 1239 | /** 1240 | * @brief Set the OV5640 camera Special Effect. 1241 | * @param pObj pointer to component object 1242 | * @param Effect Effect to be configured 1243 | * @retval Component status 1244 | */ 1245 | int32_t OV5640_SetColorEffect(OV5640_Object_t *pObj, uint32_t Effect) 1246 | { 1247 | int32_t ret; 1248 | uint8_t tmp; 1249 | 1250 | switch (Effect) 1251 | { 1252 | case OV5640_COLOR_EFFECT_BLUE: 1253 | tmp = 0xFF; 1254 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_ISP_CONTROL01, &tmp, 1); 1255 | 1256 | if (ret == OV5640_OK) 1257 | { 1258 | tmp = 0x18; 1259 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL0, &tmp, 1); 1260 | } 1261 | if (ret == OV5640_OK) 1262 | { 1263 | tmp = 0xA0; 1264 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL3, &tmp, 1); 1265 | } 1266 | if (ret == OV5640_OK) 1267 | { 1268 | tmp = 0x40; 1269 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL4, &tmp, 1); 1270 | } 1271 | 1272 | if (ret != OV5640_OK) 1273 | { 1274 | ret = OV5640_ERROR; 1275 | } 1276 | break; 1277 | 1278 | case OV5640_COLOR_EFFECT_RED: 1279 | tmp = 0xFF; 1280 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_ISP_CONTROL01, &tmp, 1); 1281 | 1282 | if (ret == OV5640_OK) 1283 | { 1284 | tmp = 0x18; 1285 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL0, &tmp, 1); 1286 | } 1287 | if (ret == OV5640_OK) 1288 | { 1289 | tmp = 0x80; 1290 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL3, &tmp, 1); 1291 | } 1292 | if (ret == OV5640_OK) 1293 | { 1294 | tmp = 0xC0; 1295 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL4, &tmp, 1); 1296 | } 1297 | 1298 | if (ret != OV5640_OK) 1299 | { 1300 | ret = OV5640_ERROR; 1301 | } 1302 | break; 1303 | 1304 | case OV5640_COLOR_EFFECT_GREEN: 1305 | tmp = 0xFF; 1306 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_ISP_CONTROL01, &tmp, 1); 1307 | 1308 | if (ret == OV5640_OK) 1309 | { 1310 | tmp = 0x18; 1311 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL0, &tmp, 1); 1312 | } 1313 | if (ret == OV5640_OK) 1314 | { 1315 | tmp = 0x60; 1316 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL3, &tmp, 1); 1317 | } 1318 | if (ret == OV5640_OK) 1319 | { 1320 | tmp = 0x60; 1321 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL4, &tmp, 1); 1322 | } 1323 | 1324 | if (ret != OV5640_OK) 1325 | { 1326 | ret = OV5640_ERROR; 1327 | } 1328 | break; 1329 | 1330 | case OV5640_COLOR_EFFECT_BW: 1331 | tmp = 0xFF; 1332 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_ISP_CONTROL01, &tmp, 1); 1333 | 1334 | if (ret == OV5640_OK) 1335 | { 1336 | tmp = 0x18; 1337 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL0, &tmp, 1); 1338 | } 1339 | if (ret == OV5640_OK) 1340 | { 1341 | tmp = 0x80; 1342 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL3, &tmp, 1); 1343 | } 1344 | if (ret == OV5640_OK) 1345 | { 1346 | tmp = 0x80; 1347 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL4, &tmp, 1); 1348 | } 1349 | 1350 | if (ret != OV5640_OK) 1351 | { 1352 | ret = OV5640_ERROR; 1353 | } 1354 | break; 1355 | 1356 | case OV5640_COLOR_EFFECT_SEPIA: 1357 | tmp = 0xFF; 1358 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_ISP_CONTROL01, &tmp, 1); 1359 | 1360 | if (ret == OV5640_OK) 1361 | { 1362 | tmp = 0x18; 1363 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL0, &tmp, 1); 1364 | } 1365 | if (ret == OV5640_OK) 1366 | { 1367 | tmp = 0x40; 1368 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL3, &tmp, 1); 1369 | } 1370 | if (ret == OV5640_OK) 1371 | { 1372 | tmp = 0xA0; 1373 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL4, &tmp, 1); 1374 | } 1375 | 1376 | if (ret != OV5640_OK) 1377 | { 1378 | ret = OV5640_ERROR; 1379 | } 1380 | break; 1381 | 1382 | case OV5640_COLOR_EFFECT_NEGATIVE: 1383 | tmp = 0xFF; 1384 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_ISP_CONTROL01, &tmp, 1); 1385 | 1386 | if (ret == OV5640_OK) 1387 | { 1388 | tmp = 0x40; 1389 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL0, &tmp, 1); 1390 | } 1391 | if (ret != OV5640_OK) 1392 | { 1393 | ret = OV5640_ERROR; 1394 | } 1395 | break; 1396 | 1397 | case OV5640_COLOR_EFFECT_NONE: 1398 | default : 1399 | tmp = 0x7F; 1400 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_ISP_CONTROL01, &tmp, 1); 1401 | 1402 | if (ret == OV5640_OK) 1403 | { 1404 | tmp = 0x00; 1405 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL0, &tmp, 1); 1406 | } 1407 | 1408 | if (ret != OV5640_OK) 1409 | { 1410 | ret = OV5640_ERROR; 1411 | } 1412 | 1413 | break; 1414 | } 1415 | 1416 | return ret; 1417 | } 1418 | 1419 | /** 1420 | * @brief Set the OV5640 camera Brightness Level. 1421 | * @note The brightness of OV5640 could be adjusted. Higher brightness will 1422 | * make the picture more bright. The side effect of higher brightness 1423 | * is the picture looks foggy. 1424 | * @param pObj pointer to component object 1425 | * @param Level Value to be configured 1426 | * @retval Component status 1427 | */ 1428 | int32_t OV5640_SetBrightness(OV5640_Object_t *pObj, int32_t Level) 1429 | { 1430 | int32_t ret; 1431 | const uint8_t brightness_level[] = {0x40U, 0x30U, 0x20U, 0x10U, 0x00U, 0x10U, 0x20U, 0x30U, 0x40U}; 1432 | uint8_t tmp; 1433 | 1434 | tmp = 0xFF; 1435 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_ISP_CONTROL01, &tmp, 1); 1436 | 1437 | if (ret == OV5640_OK) 1438 | { 1439 | tmp = brightness_level[Level + 4]; 1440 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL7, &tmp, 1); 1441 | } 1442 | if (ret == OV5640_OK) 1443 | { 1444 | tmp = 0x04; 1445 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL0, &tmp, 1); 1446 | } 1447 | 1448 | if (ret == OV5640_OK) 1449 | { 1450 | if (Level < 0) 1451 | { 1452 | tmp = 0x01; 1453 | if (ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL8, &tmp, 1) != OV5640_OK) 1454 | { 1455 | ret = OV5640_ERROR; 1456 | } 1457 | } 1458 | else 1459 | { 1460 | tmp = 0x09; 1461 | if (ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL8, &tmp, 1) != OV5640_OK) 1462 | { 1463 | ret = OV5640_ERROR; 1464 | } 1465 | } 1466 | } 1467 | 1468 | return ret; 1469 | } 1470 | 1471 | /** 1472 | * @brief Set the OV5640 camera Saturation Level. 1473 | * @note The color saturation of OV5640 could be adjusted. High color saturation 1474 | * would make the picture looks more vivid, but the side effect is the 1475 | * bigger noise and not accurate skin color. 1476 | * @param pObj pointer to component object 1477 | * @param Level Value to be configured 1478 | * @retval Component status 1479 | */ 1480 | int32_t OV5640_SetSaturation(OV5640_Object_t *pObj, int32_t Level) 1481 | { 1482 | int32_t ret; 1483 | const uint8_t saturation_level[] = {0x00U, 0x10U, 0x20U, 0x30U, 0x80U, 0x70U, 0x60U, 0x50U, 0x40U}; 1484 | uint8_t tmp; 1485 | 1486 | tmp = 0xFF; 1487 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_ISP_CONTROL01, &tmp, 1); 1488 | 1489 | if (ret == OV5640_OK) 1490 | { 1491 | tmp = saturation_level[Level + 4]; 1492 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL3, &tmp, 1); 1493 | } 1494 | if (ret == OV5640_OK) 1495 | { 1496 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL4, &tmp, 1); 1497 | } 1498 | if (ret == OV5640_OK) 1499 | { 1500 | tmp = 0x02; 1501 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL0, &tmp, 1); 1502 | } 1503 | 1504 | if (ret == OV5640_OK) 1505 | { 1506 | tmp = 0x41; 1507 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL8, &tmp, 1); 1508 | } 1509 | 1510 | if (ret != OV5640_OK) 1511 | { 1512 | ret = OV5640_ERROR; 1513 | } 1514 | 1515 | return ret; 1516 | } 1517 | 1518 | /** 1519 | * @brief Set the OV5640 camera Contrast Level. 1520 | * @note The contrast of OV5640 could be adjusted. Higher contrast will make 1521 | * the picture sharp. But the side effect is losing dynamic range. 1522 | * @param pObj pointer to component object 1523 | * @param Level Value to be configured 1524 | * @retval Component status 1525 | */ 1526 | int32_t OV5640_SetContrast(OV5640_Object_t *pObj, int32_t Level) 1527 | { 1528 | int32_t ret; 1529 | const uint8_t contrast_level[] = {0x10U, 0x14U, 0x18U, 0x1CU, 0x20U, 0x24U, 0x28U, 0x2CU, 0x30U}; 1530 | uint8_t tmp; 1531 | 1532 | tmp = 0xFF; 1533 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_ISP_CONTROL01, &tmp, 1); 1534 | 1535 | if (ret == OV5640_OK) 1536 | { 1537 | tmp = 0x04; 1538 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL0, &tmp, 1); 1539 | } 1540 | if (ret == OV5640_OK) 1541 | { 1542 | tmp = contrast_level[Level + 4]; 1543 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL6, &tmp, 1); 1544 | } 1545 | if (ret == OV5640_OK) 1546 | { 1547 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL5, &tmp, 1); 1548 | } 1549 | if (ret == OV5640_OK) 1550 | { 1551 | tmp = 0x41; 1552 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL8, &tmp, 1); 1553 | } 1554 | 1555 | if (ret != OV5640_OK) 1556 | { 1557 | ret = OV5640_ERROR; 1558 | } 1559 | 1560 | return ret; 1561 | } 1562 | 1563 | /** 1564 | * @brief Set the OV5640 camera Hue degree. 1565 | * @param pObj pointer to component object 1566 | * @param Level Value to be configured 1567 | * @retval Component status 1568 | */ 1569 | int32_t OV5640_SetHueDegree(OV5640_Object_t *pObj, int32_t Degree) 1570 | { 1571 | int32_t ret; 1572 | const uint8_t hue_degree_ctrl1[] = {0x80U, 0x6FU, 0x40U, 0x00U, 0x40U, 0x6FU, 0x80U, 0x6FU, 0x40U, 0x00U, 0x40U, 1573 | 0x6FU 1574 | }; 1575 | const uint8_t hue_degree_ctrl2[] = {0x00U, 0x40U, 0x6FU, 0x80U, 0x6FU, 0x40U, 0x00U, 0x40U, 0x6FU, 0x80U, 0x6FU, 1576 | 0x40U 1577 | }; 1578 | const uint8_t hue_degree_ctrl8[] = {0x32U, 0x32U, 0x32U, 0x02U, 0x02U, 0x02U, 0x01U, 0x01U, 0x01U, 0x31U, 0x31U, 1579 | 0x31U 1580 | }; 1581 | uint8_t tmp; 1582 | 1583 | tmp = 0xFF; 1584 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_ISP_CONTROL01, &tmp, 1); 1585 | 1586 | if (ret == OV5640_OK) 1587 | { 1588 | tmp = 0x01; 1589 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL0, &tmp, 1); 1590 | } 1591 | if (ret == OV5640_OK) 1592 | { 1593 | tmp = hue_degree_ctrl1[Degree + 6]; 1594 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL1, &tmp, 1); 1595 | } 1596 | if (ret == OV5640_OK) 1597 | { 1598 | tmp = hue_degree_ctrl2[Degree + 6]; 1599 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL2, &tmp, 1); 1600 | } 1601 | if (ret == OV5640_OK) 1602 | { 1603 | tmp = hue_degree_ctrl8[Degree + 6]; 1604 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL8, &tmp, 1); 1605 | } 1606 | 1607 | if (ret != OV5640_OK) 1608 | { 1609 | ret = OV5640_ERROR; 1610 | } 1611 | 1612 | return ret; 1613 | } 1614 | 1615 | /** 1616 | * @brief Control OV5640 camera mirror/vflip. 1617 | * @param pObj pointer to component object 1618 | * @param Config To configure mirror, flip, both or none 1619 | * @retval Component status 1620 | */ 1621 | int32_t OV5640_MirrorFlipConfig(OV5640_Object_t *pObj, uint32_t Config) 1622 | { 1623 | int32_t ret; 1624 | uint8_t tmp3820 = 0; 1625 | uint8_t tmp3821; 1626 | 1627 | if (ov5640_read_reg(&pObj->Ctx, OV5640_TIMING_TC_REG20, &tmp3820, 1) != OV5640_OK) 1628 | { 1629 | ret = OV5640_ERROR; 1630 | } 1631 | else 1632 | { 1633 | tmp3820 &= 0xF9U; 1634 | 1635 | if (ov5640_read_reg(&pObj->Ctx, OV5640_TIMING_TC_REG21, &tmp3821, 1) != OV5640_OK) 1636 | { 1637 | ret = OV5640_ERROR; 1638 | } 1639 | else 1640 | { 1641 | ret = OV5640_OK; 1642 | tmp3821 &= 0xF9U; 1643 | 1644 | switch (Config) 1645 | { 1646 | case OV5640_MIRROR: 1647 | if (ov5640_write_reg(&pObj->Ctx, OV5640_TIMING_TC_REG20, &tmp3820, 1) != OV5640_OK) 1648 | { 1649 | ret = OV5640_ERROR; 1650 | } 1651 | else 1652 | { 1653 | tmp3821 |= 0x06U; 1654 | if (ov5640_write_reg(&pObj->Ctx, OV5640_TIMING_TC_REG21, &tmp3821, 1) != OV5640_OK) 1655 | { 1656 | ret = OV5640_ERROR; 1657 | } 1658 | } 1659 | break; 1660 | case OV5640_FLIP: 1661 | tmp3820 |= 0x06U; 1662 | if (ov5640_write_reg(&pObj->Ctx, OV5640_TIMING_TC_REG20, &tmp3820, 1) != OV5640_OK) 1663 | { 1664 | ret = OV5640_ERROR; 1665 | } 1666 | else 1667 | { 1668 | if (ov5640_write_reg(&pObj->Ctx, OV5640_TIMING_TC_REG21, &tmp3821, 1) != OV5640_OK) 1669 | { 1670 | ret = OV5640_ERROR; 1671 | } 1672 | } 1673 | break; 1674 | case OV5640_MIRROR_FLIP: 1675 | tmp3820 |= 0x06U; 1676 | if (ov5640_write_reg(&pObj->Ctx, OV5640_TIMING_TC_REG20, &tmp3820, 1) != OV5640_OK) 1677 | { 1678 | ret = OV5640_ERROR; 1679 | } 1680 | else 1681 | { 1682 | tmp3821 |= 0x06U; 1683 | if (ov5640_write_reg(&pObj->Ctx, OV5640_TIMING_TC_REG21, &tmp3821, 1) != OV5640_OK) 1684 | { 1685 | ret = OV5640_ERROR; 1686 | } 1687 | } 1688 | break; 1689 | 1690 | case OV5640_MIRROR_FLIP_NONE: 1691 | default: 1692 | if (ov5640_write_reg(&pObj->Ctx, OV5640_TIMING_TC_REG20, &tmp3820, 1) != OV5640_OK) 1693 | { 1694 | ret = OV5640_ERROR; 1695 | } 1696 | else 1697 | { 1698 | if (ov5640_write_reg(&pObj->Ctx, OV5640_TIMING_TC_REG21, &tmp3821, 1) != OV5640_OK) 1699 | { 1700 | ret = OV5640_ERROR; 1701 | } 1702 | } 1703 | break; 1704 | } 1705 | } 1706 | } 1707 | 1708 | return ret; 1709 | } 1710 | 1711 | /** 1712 | * @brief Control OV5640 camera zooming. 1713 | * @param pObj pointer to component object 1714 | * @param Zoom Zoom to be configured 1715 | * @retval Component status 1716 | */ 1717 | int32_t OV5640_ZoomConfig(OV5640_Object_t *pObj, uint32_t Zoom) 1718 | { 1719 | int32_t ret = OV5640_OK; 1720 | uint32_t res; 1721 | uint32_t zoom; 1722 | uint8_t tmp; 1723 | 1724 | /* Get camera resolution */ 1725 | if (OV5640_GetResolution(pObj, &res) != OV5640_OK) 1726 | { 1727 | ret = OV5640_ERROR; 1728 | } 1729 | else 1730 | { 1731 | zoom = Zoom; 1732 | 1733 | if (zoom == OV5640_ZOOM_x1) 1734 | { 1735 | tmp = 0x10; 1736 | if (ov5640_write_reg(&pObj->Ctx, OV5640_SCALE_CTRL0, &tmp, 1) != OV5640_OK) 1737 | { 1738 | ret = OV5640_ERROR; 1739 | } 1740 | } 1741 | else 1742 | { 1743 | switch (res) 1744 | { 1745 | case OV5640_R320x240: 1746 | case OV5640_R480x272: 1747 | zoom = zoom >> 1U; 1748 | break; 1749 | case OV5640_R640x480: 1750 | zoom = zoom >> 2U; 1751 | break; 1752 | default: 1753 | break; 1754 | } 1755 | 1756 | tmp = 0x00; 1757 | if (ov5640_write_reg(&pObj->Ctx, OV5640_SCALE_CTRL0, &tmp, 1) != OV5640_OK) 1758 | { 1759 | ret = OV5640_ERROR; 1760 | } 1761 | else 1762 | { 1763 | tmp = (uint8_t)zoom; 1764 | if (ov5640_write_reg(&pObj->Ctx, OV5640_SCALE_CTRL1, &tmp, 1) != OV5640_OK) 1765 | { 1766 | ret = OV5640_ERROR; 1767 | } 1768 | } 1769 | } 1770 | } 1771 | 1772 | return ret; 1773 | } 1774 | 1775 | /** 1776 | * @brief Enable/disable the OV5640 camera night mode. 1777 | * @param pObj pointer to component object 1778 | * @param Cmd Enable disable night mode 1779 | * @retval Component status 1780 | */ 1781 | int32_t OV5640_NightModeConfig(OV5640_Object_t *pObj, uint32_t Cmd) 1782 | { 1783 | int32_t ret; 1784 | uint8_t tmp = 0; 1785 | 1786 | if (Cmd == NIGHT_MODE_ENABLE) 1787 | { 1788 | /* Auto Frame Rate: 15fps ~ 3.75fps night mode for 60/50Hz light environment, 1789 | 24Mhz clock input,24Mhz PCLK*/ 1790 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL4, &tmp, 1); 1791 | if (ret == OV5640_OK) 1792 | { 1793 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL5, &tmp, 1); 1794 | } 1795 | if (ret == OV5640_OK) 1796 | { 1797 | tmp = 0x7C; 1798 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AEC_CTRL00, &tmp, 1); 1799 | } 1800 | if (ret == OV5640_OK) 1801 | { 1802 | tmp = 0x01; 1803 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AEC_B50_STEP_HIGH, &tmp, 1); 1804 | } 1805 | if (ret == OV5640_OK) 1806 | { 1807 | tmp = 0x27; 1808 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AEC_B50_STEP_LOW, &tmp, 1); 1809 | } 1810 | if (ret == OV5640_OK) 1811 | { 1812 | tmp = 0x00; 1813 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AEC_B60_STEP_HIGH, &tmp, 1); 1814 | } 1815 | if (ret == OV5640_OK) 1816 | { 1817 | tmp = 0xF6; 1818 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AEC_B60_STEP_LOW, &tmp, 1); 1819 | } 1820 | if (ret == OV5640_OK) 1821 | { 1822 | tmp = 0x04; 1823 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AEC_CTRL0D, &tmp, 1); 1824 | } 1825 | if (ret == OV5640_OK) 1826 | { 1827 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AEC_CTRL0E, &tmp, 1); 1828 | } 1829 | if (ret == OV5640_OK) 1830 | { 1831 | tmp = 0x0B; 1832 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AEC_CTRL02, &tmp, 1); 1833 | } 1834 | if (ret == OV5640_OK) 1835 | { 1836 | tmp = 0x88; 1837 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AEC_CTRL03, &tmp, 1); 1838 | } 1839 | if (ret == OV5640_OK) 1840 | { 1841 | tmp = 0x0B; 1842 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AEC_MAX_EXPO_HIGH, &tmp, 1); 1843 | } 1844 | if (ret == OV5640_OK) 1845 | { 1846 | tmp = 0x88; 1847 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_AEC_MAX_EXPO_LOW, &tmp, 1); 1848 | } 1849 | if (ret != OV5640_OK) 1850 | { 1851 | ret = OV5640_ERROR; 1852 | } 1853 | } 1854 | else 1855 | { 1856 | if (ov5640_read_reg(&pObj->Ctx, OV5640_AEC_CTRL00, &tmp, 1) != OV5640_OK) 1857 | { 1858 | ret = OV5640_ERROR; 1859 | } 1860 | else 1861 | { 1862 | ret = OV5640_OK; 1863 | tmp &= 0xFBU; 1864 | /* Set Bit 2 to 0 */ 1865 | if (ov5640_write_reg(&pObj->Ctx, OV5640_AEC_CTRL00, &tmp, 1) != OV5640_OK) 1866 | { 1867 | ret = OV5640_ERROR; 1868 | } 1869 | } 1870 | } 1871 | 1872 | return ret; 1873 | } 1874 | /** 1875 | * @brief Configure Embedded Synchronization mode. 1876 | * @param pObj pointer to component object 1877 | * @param pSyncCodes pointer to Embedded Codes 1878 | * @retval Component status 1879 | */ 1880 | 1881 | int32_t OV5640_EmbeddedSynchroConfig(OV5640_Object_t *pObj, OV5640_SyncCodes_t *pSyncCodes) 1882 | { 1883 | uint8_t tmp; 1884 | int32_t ret = OV5640_ERROR; 1885 | 1886 | /*[7] : SYNC code from reg 0x4732-0x4732, [1]: Enable Clip ,[0]: Enable CCIR656 */ 1887 | tmp = 0x83; 1888 | if (ov5640_write_reg(&pObj->Ctx, OV5640_CCIR656_CTRL00, &tmp, 1) == OV5640_OK) 1889 | { 1890 | tmp = pSyncCodes->FrameStartCode; 1891 | if (ov5640_write_reg(&pObj->Ctx, OV5640_CCIR656_FS, &tmp, 1) == OV5640_OK) 1892 | { 1893 | tmp = pSyncCodes->FrameEndCode; 1894 | if (ov5640_write_reg(&pObj->Ctx, OV5640_CCIR656_FE, &tmp, 1) != OV5640_OK) 1895 | { 1896 | return OV5640_ERROR; 1897 | } 1898 | tmp = pSyncCodes->LineStartCode; 1899 | if (ov5640_write_reg(&pObj->Ctx, OV5640_CCIR656_LS, &tmp, 1) == OV5640_OK) 1900 | { 1901 | tmp = pSyncCodes->LineEndCode; 1902 | if (ov5640_write_reg(&pObj->Ctx, OV5640_CCIR656_LE, &tmp, 1) == OV5640_OK) 1903 | { 1904 | /*Adding 1 dummy line */ 1905 | tmp = 0x01; 1906 | if (ov5640_write_reg(&pObj->Ctx, OV5640_656_DUMMY_LINE, &tmp, 1) == OV5640_OK) 1907 | { 1908 | ret = OV5640_OK; 1909 | } 1910 | } 1911 | } 1912 | } 1913 | } 1914 | 1915 | /* max clip value[9:8], to avoid SYNC code clipping */ 1916 | tmp = 0x2; 1917 | if (ret == OV5640_OK) 1918 | { 1919 | ret = ov5640_write_reg(&pObj->Ctx, 0x4302, &tmp, 1); 1920 | } 1921 | if (ret == OV5640_OK) 1922 | { 1923 | ret = ov5640_write_reg(&pObj->Ctx, 0x4306, &tmp, 1); 1924 | } 1925 | if (ret == OV5640_OK) 1926 | { 1927 | ret = ov5640_write_reg(&pObj->Ctx, 0x430A, &tmp, 1); 1928 | } 1929 | 1930 | return ret; 1931 | } 1932 | /** 1933 | * @brief Enable/disable the OV5640 color bar mode. 1934 | * @param pObj pointer to component object 1935 | * @param Cmd Enable disable colorbar 1936 | * @retval Component status 1937 | */ 1938 | int32_t OV5640_ColorbarModeConfig(OV5640_Object_t *pObj, uint32_t Cmd) 1939 | { 1940 | int32_t ret; 1941 | uint8_t tmp = 0x40; 1942 | 1943 | if ((Cmd == COLORBAR_MODE_ENABLE) || (Cmd == COLORBAR_MODE_GRADUALV)) 1944 | { 1945 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL4, &tmp, 1); 1946 | if (ret == OV5640_OK) 1947 | { 1948 | tmp = (Cmd == COLORBAR_MODE_GRADUALV ? 0x8c : 0x80); 1949 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_PRE_ISP_TEST_SETTING1, &tmp, 1); 1950 | } 1951 | if (ret != OV5640_OK) 1952 | { 1953 | ret = OV5640_ERROR; 1954 | } 1955 | } 1956 | else 1957 | { 1958 | tmp = 0x10; 1959 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SDE_CTRL4, &tmp, 1); 1960 | if (ret == OV5640_OK) 1961 | { 1962 | tmp = 0x00; 1963 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_PRE_ISP_TEST_SETTING1, &tmp, 1); 1964 | } 1965 | if (ret != OV5640_OK) 1966 | { 1967 | ret = OV5640_ERROR; 1968 | } 1969 | } 1970 | 1971 | return ret; 1972 | } 1973 | 1974 | /** 1975 | * @brief Set the camera pixel clock 1976 | * @param pObj pointer to component object 1977 | * @param ClockValue Can be OV5640_PCLK_48M, OV5640_PCLK_24M, OV5640_PCLK_12M, OV5640_PCLK_9M 1978 | * OV5640_PCLK_8M, OV5640_PCLK_7M 1979 | * @retval Component status 1980 | */ 1981 | int32_t OV5640_SetPCLK(OV5640_Object_t *pObj, uint32_t ClockValue) 1982 | { 1983 | int32_t ret; 1984 | uint8_t tmp; 1985 | 1986 | switch (ClockValue) 1987 | { 1988 | case OV5640_PCLK_7M: 1989 | tmp = 0x38; 1990 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL2, &tmp, 1); 1991 | tmp = 0x16; 1992 | ret += ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL3, &tmp, 1); 1993 | break; 1994 | case OV5640_PCLK_8M: 1995 | tmp = 0x40; 1996 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL2, &tmp, 1); 1997 | tmp = 0x16; 1998 | ret += ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL3, &tmp, 1); 1999 | break; 2000 | case OV5640_PCLK_9M: 2001 | tmp = 0x60; 2002 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL2, &tmp, 1); 2003 | tmp = 0x18; 2004 | ret += ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL3, &tmp, 1); 2005 | break; 2006 | case OV5640_PCLK_12M: 2007 | tmp = 0x60; 2008 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL2, &tmp, 1); 2009 | tmp = 0x16; 2010 | ret += ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL3, &tmp, 1); 2011 | break; 2012 | case OV5640_PCLK_48M: 2013 | tmp = 0x60; 2014 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL2, &tmp, 1); 2015 | tmp = 0x03; 2016 | ret += ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL3, &tmp, 1); 2017 | break; 2018 | case OV5640_PCLK_24M: 2019 | default: 2020 | tmp = 0x60; 2021 | ret = ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL2, &tmp, 1); 2022 | tmp = 0x13; 2023 | ret += ov5640_write_reg(&pObj->Ctx, OV5640_SC_PLL_CONTRL3, &tmp, 1); 2024 | break; 2025 | } 2026 | 2027 | if (ret != OV5640_OK) 2028 | { 2029 | ret = OV5640_ERROR; 2030 | } 2031 | 2032 | return ret; 2033 | } 2034 | 2035 | /** 2036 | * @brief Enable DVP(Digital Video Port) Mode: Parallel Data Output 2037 | * @param pObj pointer to component object 2038 | * @retval Component status 2039 | */ 2040 | int OV5640_EnableDVPMode(OV5640_Object_t *pObj) 2041 | { 2042 | uint32_t index; 2043 | int32_t ret = OV5640_OK; 2044 | uint8_t tmp; 2045 | 2046 | 2047 | static const uint16_t regs[10][2] = 2048 | { 2049 | /* Configure the IO Pad, output FREX/VSYNC/HREF/PCLK/D[9:2]/GPIO0/GPIO1 */ 2050 | {OV5640_PAD_OUTPUT_ENABLE01, 0xFF}, 2051 | {OV5640_PAD_OUTPUT_ENABLE02, 0xF3}, 2052 | {0x302e, 0x00}, 2053 | /* Unknown DVP control configuration */ 2054 | {0x471c, 0x50}, 2055 | {OV5640_MIPI_CONTROL00, 0x58}, 2056 | /* Timing configuration */ 2057 | {OV5640_SC_PLL_CONTRL0, 0x18}, 2058 | {OV5640_SC_PLL_CONTRL1, 0x41}, 2059 | {OV5640_SC_PLL_CONTRL2, 0x60}, 2060 | {OV5640_SC_PLL_CONTRL3, 0x13}, 2061 | {OV5640_SYSTEM_ROOT_DIVIDER, 0x01}, 2062 | }; 2063 | 2064 | for(index=0; index < sizeof(regs) / 4U ; index++) 2065 | { 2066 | tmp = (uint8_t)regs[index][1]; 2067 | if(ov5640_write_reg(&pObj->Ctx, regs[index][0], &tmp, 1) != OV5640_OK) 2068 | { 2069 | ret = OV5640_ERROR; 2070 | break; 2071 | } 2072 | } 2073 | 2074 | return ret; 2075 | } 2076 | 2077 | /** 2078 | * @brief Enable MIPI (Mobile Industry Processor Interface) Mode: Serial port 2079 | * @param pObj pointer to component object 2080 | * @retval Component status 2081 | */ 2082 | int32_t OV5640_EnableMIPIMode(OV5640_Object_t *pObj) 2083 | { 2084 | int32_t ret = OV5640_OK; 2085 | uint8_t tmp; 2086 | uint32_t index; 2087 | 2088 | static const uint16_t regs[14][2] = 2089 | { 2090 | /* PAD settings */ 2091 | {OV5640_PAD_OUTPUT_ENABLE01, 0}, 2092 | {OV5640_PAD_OUTPUT_ENABLE02, 0}, 2093 | {0x302e, 0x08}, 2094 | /* Pixel clock period */ 2095 | {OV5640_PCLK_PERIOD, 0x23}, 2096 | /* Timing configuration */ 2097 | {OV5640_SC_PLL_CONTRL0, 0x18}, 2098 | {OV5640_SC_PLL_CONTRL1, 0x12}, 2099 | {OV5640_SC_PLL_CONTRL2, 0x1C}, 2100 | {OV5640_SC_PLL_CONTRL3, 0x13}, 2101 | {OV5640_SYSTEM_ROOT_DIVIDER, 0x01}, 2102 | {0x4814, 0x2a}, 2103 | {OV5640_MIPI_CTRL00, 0x24}, 2104 | {OV5640_PAD_OUTPUT_VALUE00, 0x70}, 2105 | {OV5640_MIPI_CONTROL00, 0x45}, 2106 | {OV5640_FRAME_CTRL02, 0x00}, 2107 | }; 2108 | 2109 | for(index=0; index < sizeof(regs) / 4U ; index++) 2110 | { 2111 | tmp = (uint8_t)regs[index][1]; 2112 | if(ov5640_write_reg(&pObj->Ctx, regs[index][0], &tmp, 1) != OV5640_OK) 2113 | { 2114 | ret = OV5640_ERROR; 2115 | break; 2116 | } 2117 | } 2118 | 2119 | return ret; 2120 | } 2121 | 2122 | /** 2123 | * @brief Set MIPI VirtualChannel 2124 | * @param pObj pointer to component object 2125 | * @param vchannel virtual channel for Mipi Mode 2126 | * @retval Component status 2127 | */ 2128 | int32_t OV5640_SetMIPIVirtualChannel(OV5640_Object_t *pObj, uint32_t vchannel) 2129 | { 2130 | int32_t ret = OV5640_OK; 2131 | uint8_t tmp; 2132 | 2133 | if (ov5640_read_reg(&pObj->Ctx, 0x4814, &tmp, 1) != OV5640_OK) 2134 | { 2135 | ret = OV5640_ERROR; 2136 | } 2137 | else 2138 | { 2139 | tmp &= ~(3 << 6); 2140 | tmp |= (vchannel << 6); 2141 | if (ov5640_write_reg(&pObj->Ctx, 0x4814, &tmp, 1) != OV5640_OK) 2142 | { 2143 | ret = OV5640_ERROR; 2144 | } 2145 | } 2146 | 2147 | return ret; 2148 | } 2149 | 2150 | /** 2151 | * @brief Start camera 2152 | * @param pObj pointer to component object 2153 | * @retval Component status 2154 | */ 2155 | int32_t OV5640_Start(OV5640_Object_t *pObj) 2156 | { 2157 | uint8_t tmp; 2158 | 2159 | tmp = 0x2; 2160 | return ov5640_write_reg(&pObj->Ctx, OV5640_SYSTEM_CTROL0, &tmp, 1); 2161 | } 2162 | 2163 | /** 2164 | * @brief Stop camera 2165 | * @param pObj pointer to component object 2166 | * @retval Component status 2167 | */ 2168 | int32_t OV5640_Stop(OV5640_Object_t *pObj) 2169 | { 2170 | uint8_t tmp; 2171 | 2172 | tmp = 0x42; 2173 | return ov5640_write_reg(&pObj->Ctx, OV5640_SYSTEM_CTROL0, &tmp, 1); 2174 | 2175 | } 2176 | 2177 | 2178 | /** 2179 | * @} 2180 | */ 2181 | 2182 | /** @defgroup OV5640_Private_Functions Private Functions 2183 | * @{ 2184 | */ 2185 | /** 2186 | * @brief This function provides accurate delay (in milliseconds) 2187 | * @param pObj pointer to component object 2188 | * @param Delay specifies the delay time length, in milliseconds 2189 | * @retval OV5640_OK 2190 | */ 2191 | static int32_t OV5640_Delay(OV5640_Object_t *pObj, uint32_t Delay) 2192 | { 2193 | uint32_t tickstart; 2194 | tickstart = pObj->IO.GetTick(); 2195 | while ((pObj->IO.GetTick() - tickstart) < Delay) 2196 | { 2197 | } 2198 | return OV5640_OK; 2199 | } 2200 | 2201 | /** 2202 | * @brief Wrap component ReadReg to Bus Read function 2203 | * @param handle Component object handle 2204 | * @param Reg The target register address to write 2205 | * @param pData The target register value to be written 2206 | * @param Length buffer size to be written 2207 | * @retval error status 2208 | */ 2209 | static int32_t OV5640_ReadRegWrap(void *handle, uint16_t Reg, uint8_t *pData, uint16_t Length) 2210 | { 2211 | OV5640_Object_t *pObj = (OV5640_Object_t *)handle; 2212 | 2213 | return pObj->IO.ReadReg(pObj->IO.Address, Reg, pData, Length); 2214 | } 2215 | 2216 | /** 2217 | * @brief Wrap component WriteReg to Bus Write function 2218 | * @param handle Component object handle 2219 | * @param Reg The target register address to write 2220 | * @param pData The target register value to be written 2221 | * @param Length buffer size to be written 2222 | * @retval error status 2223 | */ 2224 | static int32_t OV5640_WriteRegWrap(void *handle, uint16_t Reg, uint8_t *pData, uint16_t Length) 2225 | { 2226 | OV5640_Object_t *pObj = (OV5640_Object_t *)handle; 2227 | 2228 | return pObj->IO.WriteReg(pObj->IO.Address, Reg, pData, Length); 2229 | } 2230 | 2231 | /** 2232 | * @} 2233 | */ 2234 | 2235 | /** 2236 | * @} 2237 | */ 2238 | 2239 | /** 2240 | * @} 2241 | */ 2242 | 2243 | /** 2244 | * @} 2245 | */ 2246 | -------------------------------------------------------------------------------- /ov5640.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file ov5640.h 4 | * @author MCD Application Team 5 | * @brief This file contains all the functions prototypes for the ov5640.c 6 | * driver. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | * Copyright (c) 2019-2020 STMicroelectronics. 11 | * All rights reserved. 12 | * 13 | * This software is licensed under terms that can be found in the LICENSE file 14 | * in the root directory of this software component. 15 | * If no LICENSE file comes with this software, it is provided AS-IS. 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Define to prevent recursive inclusion -------------------------------------*/ 21 | #ifndef OV5640_H 22 | #define OV5640_H 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | /* Includes ------------------------------------------------------------------*/ 29 | #include "ov5640_reg.h" 30 | #include 31 | 32 | /** @addtogroup BSP 33 | * @{ 34 | */ 35 | 36 | /** @addtogroup Components 37 | * @{ 38 | */ 39 | 40 | /** @addtogroup ov5640 41 | * @{ 42 | */ 43 | 44 | /** @defgroup OV5640_Exported_Types 45 | * @{ 46 | */ 47 | 48 | typedef int32_t (*OV5640_Init_Func)(void); 49 | typedef int32_t (*OV5640_DeInit_Func)(void); 50 | typedef int32_t (*OV5640_GetTick_Func)(void); 51 | typedef int32_t (*OV5640_Delay_Func)(uint32_t); 52 | typedef int32_t (*OV5640_WriteReg_Func)(uint16_t, uint16_t, uint8_t *, uint16_t); 53 | typedef int32_t (*OV5640_ReadReg_Func)(uint16_t, uint16_t, uint8_t *, uint16_t); 54 | 55 | typedef struct 56 | { 57 | OV5640_Init_Func Init; 58 | OV5640_DeInit_Func DeInit; 59 | uint16_t Address; 60 | OV5640_WriteReg_Func WriteReg; 61 | OV5640_ReadReg_Func ReadReg; 62 | OV5640_GetTick_Func GetTick; 63 | } OV5640_IO_t; 64 | 65 | 66 | typedef struct 67 | { 68 | OV5640_IO_t IO; 69 | ov5640_ctx_t Ctx; 70 | uint8_t IsInitialized; 71 | uint8_t Mode; 72 | uint32_t VirtualChannelID; 73 | } OV5640_Object_t; 74 | 75 | typedef struct 76 | { 77 | uint8_t FrameStartCode; /*!< Specifies the code of the frame start delimiter. */ 78 | uint8_t LineStartCode; /*!< Specifies the code of the line start delimiter. */ 79 | uint8_t LineEndCode; /*!< Specifies the code of the line end delimiter. */ 80 | uint8_t FrameEndCode; /*!< Specifies the code of the frame end delimiter. */ 81 | 82 | } OV5640_SyncCodes_t; 83 | 84 | typedef struct 85 | { 86 | uint32_t Config_Resolution; 87 | uint32_t Config_LightMode; 88 | uint32_t Config_SpecialEffect; 89 | uint32_t Config_Brightness; 90 | uint32_t Config_Saturation; 91 | uint32_t Config_Contrast; 92 | uint32_t Config_HueDegree; 93 | uint32_t Config_MirrorFlip; 94 | uint32_t Config_Zoom; 95 | uint32_t Config_NightMode; 96 | } OV5640_Capabilities_t; 97 | 98 | typedef struct 99 | { 100 | int32_t (*Init)(OV5640_Object_t *, uint32_t, uint32_t); 101 | int32_t (*DeInit)(OV5640_Object_t *); 102 | int32_t (*ReadID)(OV5640_Object_t *, uint32_t *); 103 | int32_t (*GetCapabilities)(OV5640_Object_t *, OV5640_Capabilities_t *); 104 | int32_t (*SetLightMode)(OV5640_Object_t *, uint32_t); 105 | int32_t (*SetColorEffect)(OV5640_Object_t *, uint32_t); 106 | int32_t (*SetBrightness)(OV5640_Object_t *, int32_t); 107 | int32_t (*SetSaturation)(OV5640_Object_t *, int32_t); 108 | int32_t (*SetContrast)(OV5640_Object_t *, int32_t); 109 | int32_t (*SetHueDegree)(OV5640_Object_t *, int32_t); 110 | int32_t (*MirrorFlipConfig)(OV5640_Object_t *, uint32_t); 111 | int32_t (*ZoomConfig)(OV5640_Object_t *, uint32_t); 112 | int32_t (*SetResolution)(OV5640_Object_t *, uint32_t); 113 | int32_t (*GetResolution)(OV5640_Object_t *, uint32_t *); 114 | int32_t (*SetPixelFormat)(OV5640_Object_t *, uint32_t); 115 | int32_t (*GetPixelFormat)(OV5640_Object_t *, uint32_t *); 116 | int32_t (*NightModeConfig)(OV5640_Object_t *, uint32_t); 117 | } OV5640_CAMERA_Drv_t; 118 | /** 119 | * @} 120 | */ 121 | 122 | /** @defgroup OV5640_Exported_Constants 123 | * @{ 124 | */ 125 | #define OV5640_OK (0) 126 | #define OV5640_ERROR (-1) 127 | /** 128 | * @brief OV5640 Features Parameters 129 | */ 130 | /* Camera resolutions */ 131 | #define OV5640_R160x120 0x00U /* QQVGA Resolution */ 132 | #define OV5640_R320x240 0x01U /* QVGA Resolution */ 133 | #define OV5640_R480x272 0x02U /* 480x272 Resolution */ 134 | #define OV5640_R640x480 0x03U /* VGA Resolution */ 135 | #define OV5640_R800x480 0x04U /* WVGA Resolution */ 136 | 137 | /* Camera Pixel Format */ 138 | #define OV5640_RGB565 0x00U /* Pixel Format RGB565 */ 139 | #define OV5640_RGB888 0x01U /* Pixel Format RGB888 */ 140 | #define OV5640_YUV422 0x02U /* Pixel Format YUV422 */ 141 | #define OV5640_Y8 0x07U /* Pixel Format Y8 */ 142 | #define OV5640_JPEG 0x08U /* Compressed format JPEG */ 143 | 144 | /* Polarity */ 145 | #define OV5640_POLARITY_PCLK_LOW 0x00U /* Signal Active Low */ 146 | #define OV5640_POLARITY_PCLK_HIGH 0x01U /* Signal Active High */ 147 | #define OV5640_POLARITY_HREF_LOW 0x00U /* Signal Active Low */ 148 | #define OV5640_POLARITY_HREF_HIGH 0x01U /* Signal Active High */ 149 | #define OV5640_POLARITY_VSYNC_LOW 0x01U /* Signal Active Low */ 150 | #define OV5640_POLARITY_VSYNC_HIGH 0x00U /* Signal Active High */ 151 | 152 | /* Mirror/Flip */ 153 | #define OV5640_MIRROR_FLIP_NONE 0x00U /* Set camera normal mode */ 154 | #define OV5640_FLIP 0x01U /* Set camera flip config */ 155 | #define OV5640_MIRROR 0x02U /* Set camera mirror config */ 156 | #define OV5640_MIRROR_FLIP 0x03U /* Set camera mirror and flip */ 157 | 158 | /* Zoom */ 159 | #define OV5640_ZOOM_x8 0x00U /* Set zoom to x8 */ 160 | #define OV5640_ZOOM_x4 0x11U /* Set zoom to x4 */ 161 | #define OV5640_ZOOM_x2 0x22U /* Set zoom to x2 */ 162 | #define OV5640_ZOOM_x1 0x44U /* Set zoom to x1 */ 163 | 164 | /* Special Effect */ 165 | #define OV5640_COLOR_EFFECT_NONE 0x00U /* No effect */ 166 | #define OV5640_COLOR_EFFECT_BLUE 0x01U /* Blue effect */ 167 | #define OV5640_COLOR_EFFECT_RED 0x02U /* Red effect */ 168 | #define OV5640_COLOR_EFFECT_GREEN 0x04U /* Green effect */ 169 | #define OV5640_COLOR_EFFECT_BW 0x08U /* Black and White effect */ 170 | #define OV5640_COLOR_EFFECT_SEPIA 0x10U /* Sepia effect */ 171 | #define OV5640_COLOR_EFFECT_NEGATIVE 0x20U /* Negative effect */ 172 | 173 | 174 | /* Light Mode */ 175 | #define OV5640_LIGHT_AUTO 0x00U /* Light Mode Auto */ 176 | #define OV5640_LIGHT_SUNNY 0x01U /* Light Mode Sunny */ 177 | #define OV5640_LIGHT_OFFICE 0x02U /* Light Mode Office */ 178 | #define OV5640_LIGHT_HOME 0x04U /* Light Mode Home */ 179 | #define OV5640_LIGHT_CLOUDY 0x08U /* Light Mode Claudy */ 180 | 181 | /* Night Mode */ 182 | #define NIGHT_MODE_DISABLE 0x00U /* Disable night mode */ 183 | #define NIGHT_MODE_ENABLE 0x01U /* Enable night mode */ 184 | 185 | /* Colorbar Mode */ 186 | #define COLORBAR_MODE_DISABLE 0x00U /* Disable colorbar mode */ 187 | #define COLORBAR_MODE_ENABLE 0x01U /* 8 bars W/Y/C/G/M/R/B/Bl */ 188 | #define COLORBAR_MODE_GRADUALV 0x02U /* Gradual vertical colorbar */ 189 | 190 | /* Pixel Clock */ 191 | #define OV5640_PCLK_7M 0x00U /* Pixel Clock set to 7Mhz */ 192 | #define OV5640_PCLK_8M 0x01U /* Pixel Clock set to 8Mhz */ 193 | #define OV5640_PCLK_9M 0x02U /* Pixel Clock set to 9Mhz */ 194 | #define OV5640_PCLK_12M 0x04U /* Pixel Clock set to 12Mhz */ 195 | #define OV5640_PCLK_24M 0x08U /* Pixel Clock set to 24Mhz */ 196 | #define OV5640_PCLK_48M 0x09U /* Pixel Clock set to 48MHz */ 197 | 198 | /* Mode */ 199 | #define PARALLEL_MODE 0x00U /* Parallel Interface Mode */ 200 | #define SERIAL_MODE 0x01U /* Serial Interface Mode */ 201 | 202 | /** 203 | * @} 204 | */ 205 | 206 | /** @defgroup OV5640_Exported_Functions OV5640 Exported Functions 207 | * @{ 208 | */ 209 | int32_t OV5640_RegisterBusIO(OV5640_Object_t *pObj, OV5640_IO_t *pIO); 210 | int32_t OV5640_Init(OV5640_Object_t *pObj, uint32_t Resolution, uint32_t PixelFormat); 211 | int32_t OV5640_DeInit(OV5640_Object_t *pObj); 212 | int32_t OV5640_ReadID(OV5640_Object_t *pObj, uint32_t *Id); 213 | int32_t OV5640_GetCapabilities(OV5640_Object_t *pObj, OV5640_Capabilities_t *Capabilities); 214 | int32_t OV5640_SetLightMode(OV5640_Object_t *pObj, uint32_t LightMode); 215 | int32_t OV5640_SetColorEffect(OV5640_Object_t *pObj, uint32_t Effect); 216 | int32_t OV5640_SetBrightness(OV5640_Object_t *pObj, int32_t Level); 217 | int32_t OV5640_SetSaturation(OV5640_Object_t *pObj, int32_t Level); 218 | int32_t OV5640_SetContrast(OV5640_Object_t *pObj, int32_t Level); 219 | int32_t OV5640_SetHueDegree(OV5640_Object_t *pObj, int32_t Degree); 220 | int32_t OV5640_MirrorFlipConfig(OV5640_Object_t *pObj, uint32_t Config); 221 | int32_t OV5640_ZoomConfig(OV5640_Object_t *pObj, uint32_t Zoom); 222 | int32_t OV5640_SetResolution(OV5640_Object_t *pObj, uint32_t Resolution); 223 | int32_t OV5640_GetResolution(OV5640_Object_t *pObj, uint32_t *Resolution); 224 | int32_t OV5640_SetPixelFormat(OV5640_Object_t *pObj, uint32_t PixelFormat); 225 | int32_t OV5640_GetPixelFormat(OV5640_Object_t *pObj, uint32_t *PixelFormat); 226 | int32_t OV5640_SetPolarities(OV5640_Object_t *pObj, uint32_t PclkPolarity, uint32_t HrefPolarity, 227 | uint32_t VsyncPolarity); 228 | int32_t OV5640_GetPolarities(OV5640_Object_t *pObj, uint32_t *PclkPolarity, uint32_t *HrefPolarity, 229 | uint32_t *VsyncPolarity); 230 | int32_t OV5640_NightModeConfig(OV5640_Object_t *pObj, uint32_t Cmd); 231 | int32_t OV5640_ColorbarModeConfig(OV5640_Object_t *pObj, uint32_t Cmd); 232 | int32_t OV5640_EmbeddedSynchroConfig(OV5640_Object_t *pObj, OV5640_SyncCodes_t *pSyncCodes); 233 | int32_t OV5640_SetPCLK(OV5640_Object_t *pObj, uint32_t ClockValue); 234 | 235 | int OV5640_EnableDVPMode(OV5640_Object_t *pObj); 236 | int32_t OV5640_EnableMIPIMode(OV5640_Object_t *pObj); 237 | int32_t OV5640_SetMIPIVirtualChannel(OV5640_Object_t *pObj, uint32_t vchannel); 238 | int32_t OV5640_Start(OV5640_Object_t *pObj); 239 | int32_t OV5640_Stop(OV5640_Object_t *pObj); 240 | 241 | /* CAMERA driver structure */ 242 | extern OV5640_CAMERA_Drv_t OV5640_CAMERA_Driver; 243 | /** 244 | * @} 245 | */ 246 | #ifdef __cplusplus 247 | } 248 | #endif 249 | 250 | #endif /* OV5640_H */ 251 | /** 252 | * @} 253 | */ 254 | 255 | /** 256 | * @} 257 | */ 258 | 259 | /** 260 | * @} 261 | */ 262 | -------------------------------------------------------------------------------- /ov5640_reg.c: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file ov5640_reg.c 4 | * @author MCD Application Team 5 | * @brief This file provides unitary register function to control the OV5640 6 | * Camera driver. 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | * Copyright (c) 2019-2020 STMicroelectronics. 11 | * All rights reserved. 12 | * 13 | * This software is licensed under terms that can be found in the LICENSE file 14 | * in the root directory of this software component. 15 | * If no LICENSE file comes with this software, it is provided AS-IS. 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Includes ------------------------------------------------------------------*/ 21 | #include "ov5640_reg.h" 22 | 23 | /** @addtogroup BSP 24 | * @{ 25 | */ 26 | 27 | /** @addtogroup Components 28 | * @{ 29 | */ 30 | 31 | /** @addtogroup OV5640 32 | * @brief This file provides a set of functions needed to drive the 33 | * OV5640 Camera sensor. 34 | * @{ 35 | */ 36 | 37 | /** 38 | * @brief Read OV5640 component registers 39 | * @param ctx component context 40 | * @param reg Register to read from 41 | * @param pdata Pointer to data buffer 42 | * @param length Number of data to read 43 | * @retval Component status 44 | */ 45 | int32_t ov5640_read_reg(ov5640_ctx_t *ctx, uint16_t reg, uint8_t *pdata, uint16_t length) 46 | { 47 | return ctx->ReadReg(ctx->handle, reg, pdata, length); 48 | } 49 | 50 | /** 51 | * @brief Write OV5640 component registers 52 | * @param ctx component context 53 | * @param reg Register to write to 54 | * @param pdata Pointer to data buffer 55 | * @param length Number of data to write 56 | * @retval Component status 57 | */ 58 | int32_t ov5640_write_reg(ov5640_ctx_t *ctx, uint16_t reg, uint8_t *data, uint16_t length) 59 | { 60 | return ctx->WriteReg(ctx->handle, reg, data, length); 61 | } 62 | 63 | /** 64 | * @} 65 | */ 66 | 67 | /** 68 | * @} 69 | */ 70 | 71 | /** 72 | * @} 73 | */ 74 | -------------------------------------------------------------------------------- /ov5640_reg.h: -------------------------------------------------------------------------------- 1 | /** 2 | ****************************************************************************** 3 | * @file ov5640_reg.h 4 | * @author MCD Application Team 5 | * @brief Header of ov5640_reg.c 6 | * 7 | ****************************************************************************** 8 | * @attention 9 | * 10 | * Copyright (c) 2019-2020 STMicroelectronics. 11 | * All rights reserved. 12 | * 13 | * This software is licensed under terms that can be found in the LICENSE file 14 | * in the root directory of this software component. 15 | * If no LICENSE file comes with this software, it is provided AS-IS. 16 | * 17 | ****************************************************************************** 18 | */ 19 | 20 | /* Define to prevent recursive inclusion -------------------------------------*/ 21 | #ifndef OV5640_REG_H 22 | #define OV5640_REG_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Includes ------------------------------------------------------------------*/ 31 | /** @addtogroup BSP 32 | * @{ 33 | */ 34 | 35 | /** @addtogroup Components 36 | * @{ 37 | */ 38 | 39 | /** @addtogroup OV5640 40 | * @{ 41 | */ 42 | 43 | /** @defgroup OV5640_Exported_Types 44 | * @{ 45 | */ 46 | 47 | /** 48 | * @} 49 | */ 50 | 51 | /** @defgroup OV5640_Exported_Constants OV5640 Exported Constants 52 | * @{ 53 | */ 54 | 55 | /** 56 | * @brief OV5640 ID 57 | */ 58 | #define OV5640_ID 0x5640U 59 | /** 60 | * @brief OV5640 Registers 61 | */ 62 | /* system and IO pad control [0x3000 ~ 0x3052] */ 63 | #define OV5640_SYSREM_RESET00 0x3000U 64 | #define OV5640_SYSREM_RESET01 0x3001U 65 | #define OV5640_SYSREM_RESET02 0x3002U 66 | #define OV5640_SYSREM_RESET03 0x3003U 67 | #define OV5640_CLOCK_ENABLE00 0x3004U 68 | #define OV5640_CLOCK_ENABLE01 0x3005U 69 | #define OV5640_CLOCK_ENABLE02 0x3006U 70 | #define OV5640_CLOCK_ENABLE03 0x3007U 71 | #define OV5640_SYSTEM_CTROL0 0x3008U 72 | #define OV5640_CHIP_ID_HIGH_BYTE 0x300AU 73 | #define OV5640_CHIP_ID_LOW_BYTE 0x300BU 74 | #define OV5640_MIPI_CONTROL00 0x300EU 75 | #define OV5640_PAD_OUTPUT_ENABLE00 0x3016U 76 | #define OV5640_PAD_OUTPUT_ENABLE01 0x3017U 77 | #define OV5640_PAD_OUTPUT_ENABLE02 0x3018U 78 | #define OV5640_PAD_OUTPUT_VALUE00 0x3019U 79 | #define OV5640_PAD_OUTPUT_VALUE01 0x301AU 80 | #define OV5640_PAD_OUTPUT_VALUE02 0x301BU 81 | #define OV5640_PAD_SELECT00 0x301CU 82 | #define OV5640_PAD_SELECT01 0x301DU 83 | #define OV5640_PAD_SELECT02 0x301EU 84 | #define OV5640_CHIP_REVISION 0x302AU 85 | #define OV5640_PAD_CONTROL00 0x301CU 86 | #define OV5640_SC_PWC 0x3031U 87 | #define OV5640_SC_PLL_CONTRL0 0x3034U 88 | #define OV5640_SC_PLL_CONTRL1 0x3035U 89 | #define OV5640_SC_PLL_CONTRL2 0x3036U 90 | #define OV5640_SC_PLL_CONTRL3 0x3037U 91 | #define OV5640_SC_PLL_CONTRL4 0x3038U 92 | #define OV5640_SC_PLL_CONTRL5 0x3039U 93 | #define OV5640_SC_PLLS_CTRL0 0x303AU 94 | #define OV5640_SC_PLLS_CTRL1 0x303BU 95 | #define OV5640_SC_PLLS_CTRL2 0x303CU 96 | #define OV5640_SC_PLLS_CTRL3 0x303DU 97 | #define OV5640_IO_PAD_VALUE00 0x3050U 98 | #define OV5640_IO_PAD_VALUE01 0x3051U 99 | #define OV5640_IO_PAD_VALUE02 0x3052U 100 | 101 | /* SCCB control [0x3100 ~ 0x3108] */ 102 | #define OV5640_SCCB_ID 0x3100U 103 | #define OV5640_SCCB_SYSTEM_CTRL0 0x3102U 104 | #define OV5640_SCCB_SYSTEM_CTRL1 0x3103U 105 | #define OV5640_SYSTEM_ROOT_DIVIDER 0x3108U 106 | 107 | /* SRB control [0x3200 ~ 0x3213] */ 108 | #define OV5640_GROUP_ADDR0 0x3200U 109 | #define OV5640_GROUP_ADDR1 0x3201U 110 | #define OV5640_GROUP_ADDR2 0x3202U 111 | #define OV5640_GROUP_ADDR3 0x3203U 112 | #define OV5640_SRM_GROUP_ACCESS 0x3212U 113 | #define OV5640_SRM_GROUP_STATUS 0x3213U 114 | 115 | /* AWB gain control [0x3400 ~ 0x3406] */ 116 | #define OV5640_AWB_R_GAIN_MSB 0x3400U 117 | #define OV5640_AWB_R_GAIN_LSB 0x3401U 118 | #define OV5640_AWB_G_GAIN_MSB 0x3402U 119 | #define OV5640_AWB_G_GAIN_LSB 0x3403U 120 | #define OV5640_AWB_B_GAIN_MSB 0x3404U 121 | #define OV5640_AWB_B_GAIN_LSB 0x3405U 122 | #define OV5640_AWB_MANUAL_CONTROL 0x3406U 123 | 124 | /* AEC/AGC control [0x3500 ~ 0x350D] */ 125 | #define OV5640_AEC_PK_EXPOSURE_19_16 0x3500U 126 | #define OV5640_AEC_PK_EXPOSURE_HIGH 0x3501U 127 | #define OV5640_AEC_PK_EXPOSURE_LOW 0x3502U 128 | #define OV5640_AEC_PK_MANUAL 0x3503U 129 | #define OV5640_AEC_PK_REAL_GAIN_9_8 0x350AU 130 | #define OV5640_AEC_PK_REAL_GAIN_LOW 0x350BU 131 | #define OV5640_AEC_PK_VTS_HIGH 0x350CU 132 | #define OV5640_AEC_PK_VTS_LOW 0x350DU 133 | 134 | /* VCM control [0x3600 ~ 0x3606] */ 135 | #define OV5640_VCM_CONTROL_0 0x3602U 136 | #define OV5640_VCM_CONTROL_1 0x3603U 137 | #define OV5640_VCM_CONTROL_2 0x3604U 138 | #define OV5640_VCM_CONTROL_3 0x3605U 139 | #define OV5640_VCM_CONTROL_4 0x3606U 140 | 141 | /* timing control [0x3800 ~ 0x3821] */ 142 | #define OV5640_TIMING_HS_HIGH 0x3800U 143 | #define OV5640_TIMING_HS_LOW 0x3801U 144 | #define OV5640_TIMING_VS_HIGH 0x3802U 145 | #define OV5640_TIMING_VS_LOW 0x3803U 146 | #define OV5640_TIMING_HW_HIGH 0x3804U 147 | #define OV5640_TIMING_HW_LOW 0x3805U 148 | #define OV5640_TIMING_VH_HIGH 0x3806U 149 | #define OV5640_TIMING_VH_LOW 0x3807U 150 | #define OV5640_TIMING_DVPHO_HIGH 0x3808U 151 | #define OV5640_TIMING_DVPHO_LOW 0x3809U 152 | #define OV5640_TIMING_DVPVO_HIGH 0x380AU 153 | #define OV5640_TIMING_DVPVO_LOW 0x380BU 154 | #define OV5640_TIMING_HTS_HIGH 0x380CU 155 | #define OV5640_TIMING_HTS_LOW 0x380DU 156 | #define OV5640_TIMING_VTS_HIGH 0x380EU 157 | #define OV5640_TIMING_VTS_LOW 0x380FU 158 | #define OV5640_TIMING_HOFFSET_HIGH 0x3810U 159 | #define OV5640_TIMING_HOFFSET_LOW 0x3811U 160 | #define OV5640_TIMING_VOFFSET_HIGH 0x3812U 161 | #define OV5640_TIMING_VOFFSET_LOW 0x3813U 162 | #define OV5640_TIMING_X_INC 0x3814U 163 | #define OV5640_TIMING_Y_INC 0x3815U 164 | #define OV5640_HSYNC_START_HIGH 0x3816U 165 | #define OV5640_HSYNC_START_LOW 0x3817U 166 | #define OV5640_HSYNC_WIDTH_HIGH 0x3818U 167 | #define OV5640_HSYNC_WIDTH_LOW 0x3819U 168 | #define OV5640_TIMING_TC_REG20 0x3820U 169 | #define OV5640_TIMING_TC_REG21 0x3821U 170 | 171 | /* AEC/AGC power down domain control [0x3A00 ~ 0x3A25] */ 172 | #define OV5640_AEC_CTRL00 0x3A00U 173 | #define OV5640_AEC_CTRL01 0x3A01U 174 | #define OV5640_AEC_CTRL02 0x3A02U 175 | #define OV5640_AEC_CTRL03 0x3A03U 176 | #define OV5640_AEC_CTRL04 0x3A04U 177 | #define OV5640_AEC_CTRL05 0x3A05U 178 | #define OV5640_AEC_CTRL06 0x3A06U 179 | #define OV5640_AEC_CTRL07 0x3A07U 180 | #define OV5640_AEC_B50_STEP_HIGH 0x3A08U 181 | #define OV5640_AEC_B50_STEP_LOW 0x3A09U 182 | #define OV5640_AEC_B60_STEP_HIGH 0x3A0AU 183 | #define OV5640_AEC_B60_STEP_LOW 0x3A0BU 184 | #define OV5640_AEC_AEC_CTRL0C 0x3A0CU 185 | #define OV5640_AEC_CTRL0D 0x3A0DU 186 | #define OV5640_AEC_CTRL0E 0x3A0EU 187 | #define OV5640_AEC_CTRL0F 0x3A0FU 188 | #define OV5640_AEC_CTRL10 0x3A10U 189 | #define OV5640_AEC_CTRL11 0x3A11U 190 | #define OV5640_AEC_CTRL13 0x3A13U 191 | #define OV5640_AEC_MAX_EXPO_HIGH 0x3A14U 192 | #define OV5640_AEC_MAX_EXPO_LOW 0x3A15U 193 | #define OV5640_AEC_CTRL17 0x3A17U 194 | #define OV5640_AEC_GAIN_CEILING_HIGH 0x3A18U 195 | #define OV5640_AEC_GAIN_CEILING_LOW 0x3A19U 196 | #define OV5640_AEC_DIFF_MIN 0x3A1AU 197 | #define OV5640_AEC_CTRL1B 0x3A1BU 198 | #define OV5640_LED_ADD_ROW_HIGH 0x3A1CU 199 | #define OV5640_LED_ADD_ROW_LOW 0x3A1DU 200 | #define OV5640_AEC_CTRL1E 0x3A1EU 201 | #define OV5640_AEC_CTRL1F 0x3A1FU 202 | #define OV5640_AEC_CTRL20 0x3A20U 203 | #define OV5640_AEC_CTRL21 0x3A21U 204 | #define OV5640_AEC_CTRL25 0x3A25U 205 | 206 | /* strobe control [0x3B00 ~ 0x3B0C] */ 207 | #define OV5640_STROBE_CTRL 0x3B00U 208 | #define OV5640_FREX_EXPOSURE02 0x3B01U 209 | #define OV5640_FREX_SHUTTER_DLY01 0x3B02U 210 | #define OV5640_FREX_SHUTTER_DLY00 0x3B03U 211 | #define OV5640_FREX_EXPOSURE01 0x3B04U 212 | #define OV5640_FREX_EXPOSURE00 0x3B05U 213 | #define OV5640_FREX_CTRL07 0x3B06U 214 | #define OV5640_FREX_MODE 0x3B07U 215 | #define OV5640_FREX_RQST 0x3B08U 216 | #define OV5640_FREX_HREF_DLY 0x3B09U 217 | #define OV5640_FREX_RST_LENGTH 0x3B0AU 218 | #define OV5640_STROBE_WIDTH_HIGH 0x3B0BU 219 | #define OV5640_STROBE_WIDTH_LOW 0x3B0CU 220 | 221 | /* 50/60Hz detector control [0x3C00 ~ 0x3C1E] */ 222 | #define OV5640_5060HZ_CTRL00 0x3C00U 223 | #define OV5640_5060HZ_CTRL01 0x3C01U 224 | #define OV5640_5060HZ_CTRL02 0x3C02U 225 | #define OV5640_5060HZ_CTRL03 0x3C03U 226 | #define OV5640_5060HZ_CTRL04 0x3C04U 227 | #define OV5640_5060HZ_CTRL05 0x3C05U 228 | #define OV5640_LIGHTMETER1_TH_HIGH 0x3C06U 229 | #define OV5640_LIGHTMETER1_TH_LOW 0x3C07U 230 | #define OV5640_LIGHTMETER2_TH_HIGH 0x3C08U 231 | #define OV5640_LIGHTMETER2_TH_LOW 0x3C09U 232 | #define OV5640_SAMPLE_NUMBER_HIGH 0x3C0AU 233 | #define OV5640_SAMPLE_NUMBER_LOW 0x3C0BU 234 | #define OV5640_SIGMA_DELTA_CTRL0C 0x3C0CU 235 | #define OV5640_SUM50_BYTE4 0x3C0DU 236 | #define OV5640_SUM50_BYTE3 0x3C0EU 237 | #define OV5640_SUM50_BYTE2 0x3C0FU 238 | #define OV5640_SUM50_BYTE1 0x3C10U 239 | #define OV5640_SUM60_BYTE4 0x3C11U 240 | #define OV5640_SUM60_BYTE3 0x3C12U 241 | #define OV5640_SUM60_BYTE2 0x3C13U 242 | #define OV5640_SUM60_BYTE1 0x3C14U 243 | #define OV5640_SUM5060_HIGH 0x3C15U 244 | #define OV5640_SUM5060_LOW 0x3C16U 245 | #define OV5640_BLOCK_CNTR_HIGH 0x3C17U 246 | #define OV5640_BLOCK_CNTR_LOW 0x3C18U 247 | #define OV5640_B6_HIGH 0x3C19U 248 | #define OV5640_B6_LOW 0x3C1AU 249 | #define OV5640_LIGHTMETER_OUTPUT_BYTE3 0x3C1BU 250 | #define OV5640_LIGHTMETER_OUTPUT_BYTE2 0x3C1CU 251 | #define OV5640_LIGHTMETER_OUTPUT_BYTE1 0x3C1DU 252 | #define OV5640_SUM_THRESHOLD 0x3C1EU 253 | 254 | /* OTP control [0x3D00 ~ 0x3D21] */ 255 | /* MC control [0x3F00 ~ 0x3F0D] */ 256 | /* BLC control [0x4000 ~ 0x4033] */ 257 | #define OV5640_BLC_CTRL00 0x4000U 258 | #define OV5640_BLC_CTRL01 0x4001U 259 | #define OV5640_BLC_CTRL02 0x4002U 260 | #define OV5640_BLC_CTRL03 0x4003U 261 | #define OV5640_BLC_CTRL04 0x4004U 262 | #define OV5640_BLC_CTRL05 0x4005U 263 | 264 | /* frame control [0x4201 ~ 0x4202] */ 265 | #define OV5640_FRAME_CTRL01 0x4201U 266 | #define OV5640_FRAME_CTRL02 0x4202U 267 | 268 | /* format control [0x4300 ~ 0x430D] */ 269 | #define OV5640_FORMAT_CTRL00 0x4300U 270 | #define OV5640_FORMAT_CTRL01 0x4301U 271 | #define OV5640_YMAX_VAL_HIGH 0x4302U 272 | #define OV5640_YMAX_VAL_LOW 0x4303U 273 | #define OV5640_YMIN_VAL_HIGH 0x4304U 274 | #define OV5640_YMIN_VAL_LOW 0x4305U 275 | #define OV5640_UMAX_VAL_HIGH 0x4306U 276 | #define OV5640_UMAX_VAL_LOW 0x4307U 277 | #define OV5640_UMIN_VAL_HIGH 0x4308U 278 | #define OV5640_UMIN_VAL_LOW 0x4309U 279 | #define OV5640_VMAX_VAL_HIGH 0x430AU 280 | #define OV5640_VMAX_VAL_LOW 0x430BU 281 | #define OV5640_VMIN_VAL_HIGH 0x430CU 282 | #define OV5640_VMIN_VAL_LOW 0x430DU 283 | 284 | /* JPEG control [0x4400 ~ 0x4431] */ 285 | #define OV5640_JPEG_CTRL00 0x4400U 286 | #define OV5640_JPEG_CTRL01 0x4401U 287 | #define OV5640_JPEG_CTRL02 0x4402U 288 | #define OV5640_JPEG_CTRL03 0x4403U 289 | #define OV5640_JPEG_CTRL04 0x4404U 290 | #define OV5640_JPEG_CTRL05 0x4405U 291 | #define OV5640_JPEG_CTRL06 0x4406U 292 | #define OV5640_JPEG_CTRL07 0x4407U 293 | #define OV5640_JPEG_ISI_CTRL1 0x4408U 294 | #define OV5640_JPEG_CTRL09 0x4409U 295 | #define OV5640_JPEG_CTRL0A 0x440AU 296 | #define OV5640_JPEG_CTRL0B 0x440BU 297 | #define OV5640_JPEG_CTRL0C 0x440CU 298 | #define OV5640_JPEG_QT_DATA 0x4410U 299 | #define OV5640_JPEG_QT_ADDR 0x4411U 300 | #define OV5640_JPEG_ISI_DATA 0x4412U 301 | #define OV5640_JPEG_ISI_CTRL2 0x4413U 302 | #define OV5640_JPEG_LENGTH_BYTE3 0x4414U 303 | #define OV5640_JPEG_LENGTH_BYTE2 0x4415U 304 | #define OV5640_JPEG_LENGTH_BYTE1 0x4416U 305 | #define OV5640_JFIFO_OVERFLOW 0x4417U 306 | 307 | /* VFIFO control [0x4600 ~ 0x460D] */ 308 | #define OV5640_VFIFO_CTRL00 0x4600U 309 | #define OV5640_VFIFO_HSIZE_HIGH 0x4602U 310 | #define OV5640_VFIFO_HSIZE_LOW 0x4603U 311 | #define OV5640_VFIFO_VSIZE_HIGH 0x4604U 312 | #define OV5640_VFIFO_VSIZE_LOW 0x4605U 313 | #define OV5640_VFIFO_CTRL0C 0x460CU 314 | #define OV5640_VFIFO_CTRL0D 0x460DU 315 | 316 | /* DVP control [0x4709 ~ 0x4745] */ 317 | #define OV5640_DVP_VSYNC_WIDTH0 0x4709U 318 | #define OV5640_DVP_VSYNC_WIDTH1 0x470AU 319 | #define OV5640_DVP_VSYNC_WIDTH2 0x470BU 320 | #define OV5640_PAD_LEFT_CTRL 0x4711U 321 | #define OV5640_PAD_RIGHT_CTRL 0x4712U 322 | #define OV5640_JPG_MODE_SELECT 0x4713U 323 | #define OV5640_656_DUMMY_LINE 0x4715U 324 | #define OV5640_CCIR656_CTRL 0x4719U 325 | #define OV5640_HSYNC_CTRL00 0x471BU 326 | #define OV5640_DVP_VSYN_CTRL 0x471DU 327 | #define OV5640_DVP_HREF_CTRL 0x471FU 328 | #define OV5640_VSTART_OFFSET 0x4721U 329 | #define OV5640_VEND_OFFSET 0x4722U 330 | #define OV5640_DVP_CTRL23 0x4723U 331 | #define OV5640_CCIR656_CTRL00 0x4730U 332 | #define OV5640_CCIR656_CTRL01 0x4731U 333 | #define OV5640_CCIR656_FS 0x4732U 334 | #define OV5640_CCIR656_FE 0x4733U 335 | #define OV5640_CCIR656_LS 0x4734U 336 | #define OV5640_CCIR656_LE 0x4735U 337 | #define OV5640_CCIR656_CTRL06 0x4736U 338 | #define OV5640_CCIR656_CTRL07 0x4737U 339 | #define OV5640_CCIR656_CTRL08 0x4738U 340 | #define OV5640_POLARITY_CTRL 0x4740U 341 | #define OV5640_TEST_PATTERN 0x4741U 342 | #define OV5640_DATA_ORDER 0x4745U 343 | 344 | /* MIPI control [0x4800 ~ 0x4837] */ 345 | #define OV5640_MIPI_CTRL00 0x4800U 346 | #define OV5640_MIPI_CTRL01 0x4801U 347 | #define OV5640_MIPI_CTRL05 0x4805U 348 | #define OV5640_MIPI_DATA_ORDER 0x480AU 349 | #define OV5640_MIN_HS_ZERO_HIGH 0x4818U 350 | #define OV5640_MIN_HS_ZERO_LOW 0x4819U 351 | #define OV5640_MIN_MIPI_HS_TRAIL_HIGH 0x481AU 352 | #define OV5640_MIN_MIPI_HS_TRAIL_LOW 0x481BU 353 | #define OV5640_MIN_MIPI_CLK_ZERO_HIGH 0x481CU 354 | #define OV5640_MIN_MIPI_CLK_ZERO_LOW 0x481DU 355 | #define OV5640_MIN_MIPI_CLK_PREPARE_HIGH 0x481EU 356 | #define OV5640_MIN_MIPI_CLK_PREPARE_LOW 0x481FU 357 | #define OV5640_MIN_CLK_POST_HIGH 0x4820U 358 | #define OV5640_MIN_CLK_POST_LOW 0x4821U 359 | #define OV5640_MIN_CLK_TRAIL_HIGH 0x4822U 360 | #define OV5640_MIN_CLK_TRAIL_LOW 0x4823U 361 | #define OV5640_MIN_LPX_PCLK_HIGH 0x4824U 362 | #define OV5640_MIN_LPX_PCLK_LOW 0x4825U 363 | #define OV5640_MIN_HS_PREPARE_HIGH 0x4826U 364 | #define OV5640_MIN_HS_PREPARE_LOW 0x4827U 365 | #define OV5640_MIN_HS_EXIT_HIGH 0x4828U 366 | #define OV5640_MIN_HS_EXIT_LOW 0x4829U 367 | #define OV5640_MIN_HS_ZERO_UI 0x482AU 368 | #define OV5640_MIN_HS_TRAIL_UI 0x482BU 369 | #define OV5640_MIN_CLK_ZERO_UI 0x482CU 370 | #define OV5640_MIN_CLK_PREPARE_UI 0x482DU 371 | #define OV5640_MIN_CLK_POST_UI 0x482EU 372 | #define OV5640_MIN_CLK_TRAIL_UI 0x482FU 373 | #define OV5640_MIN_LPX_PCLK_UI 0x4830U 374 | #define OV5640_MIN_HS_PREPARE_UI 0x4831U 375 | #define OV5640_MIN_HS_EXIT_UI 0x4832U 376 | #define OV5640_PCLK_PERIOD 0x4837U 377 | 378 | /* ISP frame control [0x4901 ~ 0x4902] */ 379 | #define OV5640_ISP_FRAME_CTRL01 0x4901U 380 | #define OV5640_ISP_FRAME_CTRL02 0x4902U 381 | 382 | /* ISP top control [0x5000 ~ 0x5063] */ 383 | #define OV5640_ISP_CONTROL00 0x5000U 384 | #define OV5640_ISP_CONTROL01 0x5001U 385 | #define OV5640_ISP_CONTROL03 0x5003U 386 | #define OV5640_ISP_CONTROL05 0x5005U 387 | #define OV5640_ISP_MISC0 0x501DU 388 | #define OV5640_ISP_MISC1 0x501EU 389 | #define OV5640_FORMAT_MUX_CTRL 0x501FU 390 | #define OV5640_DITHER_CTRL0 0x5020U 391 | #define OV5640_DRAW_WINDOW_CTRL00 0x5027U 392 | #define OV5640_DRAW_WINDOW_LEFT_CTRL_HIGH 0x5028U 393 | #define OV5640_DRAW_WINDOW_LEFT_CTRL_LOW 0x5029U 394 | #define OV5640_DRAW_WINDOW_RIGHT_CTRL_HIGH 0x502AU 395 | #define OV5640_DRAW_WINDOW_RIGHT_CTRL_LOW 0x502BU 396 | #define OV5640_DRAW_WINDOW_TOP_CTRL_HIGH 0x502CU 397 | #define OV5640_DRAW_WINDOW_TOP_CTRL_LOW 0x502DU 398 | #define OV5640_DRAW_WINDOW_BOTTOM_CTRL_HIGH 0x502EU 399 | #define OV5640_DRAW_WINDOW_BOTTOM_CTRL_LOW 0x502FU 400 | #define OV5640_DRAW_WINDOW_HBW_CTRL_HIGH 0x5030U /* HBW: Horizontal Boundary Width */ 401 | #define OV5640_DRAW_WINDOW_HBW_CTRL_LOW 0x5031U 402 | #define OV5640_DRAW_WINDOW_VBW_CTRL_HIGH 0x5032U /* VBW: Vertical Boundary Width */ 403 | #define OV5640_DRAW_WINDOW_VBW_CTRL_LOW 0x5033U 404 | #define OV5640_DRAW_WINDOW_Y_CTRL 0x5034U 405 | #define OV5640_DRAW_WINDOW_U_CTRL 0x5035U 406 | #define OV5640_DRAW_WINDOW_V_CTRL 0x5036U 407 | #define OV5640_PRE_ISP_TEST_SETTING1 0x503DU 408 | #define OV5640_ISP_SENSOR_BIAS_I 0x5061U 409 | #define OV5640_ISP_SENSOR_GAIN1_I 0x5062U 410 | #define OV5640_ISP_SENSOR_GAIN2_I 0x5063U 411 | 412 | /* AWB control [0x5180 ~ 0x51D0] */ 413 | #define OV5640_AWB_CTRL00 0x5180U 414 | #define OV5640_AWB_CTRL01 0x5181U 415 | #define OV5640_AWB_CTRL02 0x5182U 416 | #define OV5640_AWB_CTRL03 0x5183U 417 | #define OV5640_AWB_CTRL04 0x5184U 418 | #define OV5640_AWB_CTRL05 0x5185U 419 | #define OV5640_AWB_CTRL06 0x5186U /* Advanced AWB control registers: 0x5186 ~ 0x5190 */ 420 | #define OV5640_AWB_CTRL07 0x5187U 421 | #define OV5640_AWB_CTRL08 0x5188U 422 | #define OV5640_AWB_CTRL09 0x5189U 423 | #define OV5640_AWB_CTRL10 0x518AU 424 | #define OV5640_AWB_CTRL11 0x518BU 425 | #define OV5640_AWB_CTRL12 0x518CU 426 | #define OV5640_AWB_CTRL13 0x518DU 427 | #define OV5640_AWB_CTRL14 0x518EU 428 | #define OV5640_AWB_CTRL15 0x518FU 429 | #define OV5640_AWB_CTRL16 0x5190U 430 | #define OV5640_AWB_CTRL17 0x5191U 431 | #define OV5640_AWB_CTRL18 0x5192U 432 | #define OV5640_AWB_CTRL19 0x5193U 433 | #define OV5640_AWB_CTRL20 0x5194U 434 | #define OV5640_AWB_CTRL21 0x5195U 435 | #define OV5640_AWB_CTRL22 0x5196U 436 | #define OV5640_AWB_CTRL23 0x5197U 437 | #define OV5640_AWB_CTRL24 0x5198U 438 | #define OV5640_AWB_CTRL25 0x5199U 439 | #define OV5640_AWB_CTRL26 0x519AU 440 | #define OV5640_AWB_CTRL27 0x519BU 441 | #define OV5640_AWB_CTRL28 0x519CU 442 | #define OV5640_AWB_CTRL29 0x519DU 443 | #define OV5640_AWB_CTRL30 0x519EU 444 | #define OV5640_AWB_CURRENT_R_GAIN_HIGH 0x519FU 445 | #define OV5640_AWB_CURRENT_R_GAIN_LOW 0x51A0U 446 | #define OV5640_AWB_CURRENT_G_GAIN_HIGH 0x51A1U 447 | #define OV5640_AWB_CURRENT_G_GAIN_LOW 0x51A2U 448 | #define OV5640_AWB_CURRENT_B_GAIN_HIGH 0x51A3U 449 | #define OV5640_AWB_CURRENT_B_GAIN_LOW 0x51A4U 450 | #define OV5640_AWB_AVERAGE_R 0x51A5U 451 | #define OV5640_AWB_AVERAGE_G 0x51A6U 452 | #define OV5640_AWB_AVERAGE_B 0x51A7U 453 | #define OV5640_AWB_CTRL74 0x5180U 454 | 455 | /* CIP control [0x5300 ~ 0x530F] */ 456 | #define OV5640_CIP_SHARPENMT_TH1 0x5300U 457 | #define OV5640_CIP_SHARPENMT_TH2 0x5301U 458 | #define OV5640_CIP_SHARPENMT_OFFSET1 0x5302U 459 | #define OV5640_CIP_SHARPENMT_OFFSET2 0x5303U 460 | #define OV5640_CIP_DNS_TH1 0x5304U 461 | #define OV5640_CIP_DNS_TH2 0x5305U 462 | #define OV5640_CIP_DNS_OFFSET1 0x5306U 463 | #define OV5640_CIP_DNS_OFFSET2 0x5307U 464 | #define OV5640_CIP_CTRL 0x5308U 465 | #define OV5640_CIP_SHARPENTH_TH1 0x5309U 466 | #define OV5640_CIP_SHARPENTH_TH2 0x530AU 467 | #define OV5640_CIP_SHARPENTH_OFFSET1 0x530BU 468 | #define OV5640_CIP_SHARPENTH_OFFSET2 0x530CU 469 | #define OV5640_CIP_EDGE_MT_AUTO 0x530DU 470 | #define OV5640_CIP_DNS_TH_AUTO 0x530EU 471 | #define OV5640_CIP_SHARPEN_TH_AUTO 0x530FU 472 | 473 | /* CMX control [0x5380 ~ 0x538B] */ 474 | #define OV5640_CMX_CTRL 0x5380U 475 | #define OV5640_CMX1 0x5381U 476 | #define OV5640_CMX2 0x5382U 477 | #define OV5640_CMX3 0x5383U 478 | #define OV5640_CMX4 0x5384U 479 | #define OV5640_CMX5 0x5385U 480 | #define OV5640_CMX6 0x5386U 481 | #define OV5640_CMX7 0x5387U 482 | #define OV5640_CMX8 0x5388U 483 | #define OV5640_CMX9 0x5389U 484 | #define OV5640_CMXSIGN_HIGH 0x538AU 485 | #define OV5640_CMXSIGN_LOW 0x538BU 486 | 487 | /* gamma control [0x5480 ~ 0x5490] */ 488 | #define OV5640_GAMMA_CTRL00 0x5480U 489 | #define OV5640_GAMMA_YST00 0x5481U 490 | #define OV5640_GAMMA_YST01 0x5482U 491 | #define OV5640_GAMMA_YST02 0x5483U 492 | #define OV5640_GAMMA_YST03 0x5484U 493 | #define OV5640_GAMMA_YST04 0x5485U 494 | #define OV5640_GAMMA_YST05 0x5486U 495 | #define OV5640_GAMMA_YST06 0x5487U 496 | #define OV5640_GAMMA_YST07 0x5488U 497 | #define OV5640_GAMMA_YST08 0x5489U 498 | #define OV5640_GAMMA_YST09 0x548AU 499 | #define OV5640_GAMMA_YST0A 0x548BU 500 | #define OV5640_GAMMA_YST0B 0x548CU 501 | #define OV5640_GAMMA_YST0C 0x548DU 502 | #define OV5640_GAMMA_YST0D 0x548EU 503 | #define OV5640_GAMMA_YST0E 0x548FU 504 | #define OV5640_GAMMA_YST0F 0x5490U 505 | 506 | /* SDE control [0x5580 ~ 0x558C] */ 507 | #define OV5640_SDE_CTRL0 0x5580U 508 | #define OV5640_SDE_CTRL1 0x5581U 509 | #define OV5640_SDE_CTRL2 0x5582U 510 | #define OV5640_SDE_CTRL3 0x5583U 511 | #define OV5640_SDE_CTRL4 0x5584U 512 | #define OV5640_SDE_CTRL5 0x5585U 513 | #define OV5640_SDE_CTRL6 0x5586U 514 | #define OV5640_SDE_CTRL7 0x5587U 515 | #define OV5640_SDE_CTRL8 0x5588U 516 | #define OV5640_SDE_CTRL9 0x5589U 517 | #define OV5640_SDE_CTRL10 0x558AU 518 | #define OV5640_SDE_CTRL11 0x558BU 519 | #define OV5640_SDE_CTRL12 0x558CU 520 | 521 | /* scale control [0x5600 ~ 0x5606] */ 522 | #define OV5640_SCALE_CTRL0 0x5600U 523 | #define OV5640_SCALE_CTRL1 0x5601U 524 | #define OV5640_SCALE_CTRL2 0x5602U 525 | #define OV5640_SCALE_CTRL3 0x5603U 526 | #define OV5640_SCALE_CTRL4 0x5604U 527 | #define OV5640_SCALE_CTRL5 0x5605U 528 | #define OV5640_SCALE_CTRL6 0x5606U 529 | 530 | 531 | /* AVG control [0x5680 ~ 0x56A2] */ 532 | #define OV5640_X_START_HIGH 0x5680U 533 | #define OV5640_X_START_LOW 0x5681U 534 | #define OV5640_Y_START_HIGH 0x5682U 535 | #define OV5640_Y_START_LOW 0x5683U 536 | #define OV5640_X_WINDOW_HIGH 0x5684U 537 | #define OV5640_X_WINDOW_LOW 0x5685U 538 | #define OV5640_Y_WINDOW_HIGH 0x5686U 539 | #define OV5640_Y_WINDOW_LOW 0x5687U 540 | #define OV5640_WEIGHT00 0x5688U 541 | #define OV5640_WEIGHT01 0x5689U 542 | #define OV5640_WEIGHT02 0x568AU 543 | #define OV5640_WEIGHT03 0x568BU 544 | #define OV5640_WEIGHT04 0x568CU 545 | #define OV5640_WEIGHT05 0x568DU 546 | #define OV5640_WEIGHT06 0x568EU 547 | #define OV5640_WEIGHT07 0x568FU 548 | #define OV5640_AVG_CTRL10 0x5690U 549 | #define OV5640_AVG_WIN_00 0x5691U 550 | #define OV5640_AVG_WIN_01 0x5692U 551 | #define OV5640_AVG_WIN_02 0x5693U 552 | #define OV5640_AVG_WIN_03 0x5694U 553 | #define OV5640_AVG_WIN_10 0x5695U 554 | #define OV5640_AVG_WIN_11 0x5696U 555 | #define OV5640_AVG_WIN_12 0x5697U 556 | #define OV5640_AVG_WIN_13 0x5698U 557 | #define OV5640_AVG_WIN_20 0x5699U 558 | #define OV5640_AVG_WIN_21 0x569AU 559 | #define OV5640_AVG_WIN_22 0x569BU 560 | #define OV5640_AVG_WIN_23 0x569CU 561 | #define OV5640_AVG_WIN_30 0x569DU 562 | #define OV5640_AVG_WIN_31 0x569EU 563 | #define OV5640_AVG_WIN_32 0x569FU 564 | #define OV5640_AVG_WIN_33 0x56A0U 565 | #define OV5640_AVG_READOUT 0x56A1U 566 | #define OV5640_AVG_WEIGHT_SUM 0x56A2U 567 | 568 | /* LENC control [0x5800 ~ 0x5849] */ 569 | #define OV5640_GMTRX00 0x5800U 570 | #define OV5640_GMTRX01 0x5801U 571 | #define OV5640_GMTRX02 0x5802U 572 | #define OV5640_GMTRX03 0x5803U 573 | #define OV5640_GMTRX04 0x5804U 574 | #define OV5640_GMTRX05 0x5805U 575 | #define OV5640_GMTRX10 0x5806U 576 | #define OV5640_GMTRX11 0x5807U 577 | #define OV5640_GMTRX12 0x5808U 578 | #define OV5640_GMTRX13 0x5809U 579 | #define OV5640_GMTRX14 0x580AU 580 | #define OV5640_GMTRX15 0x580BU 581 | #define OV5640_GMTRX20 0x580CU 582 | #define OV5640_GMTRX21 0x580DU 583 | #define OV5640_GMTRX22 0x580EU 584 | #define OV5640_GMTRX23 0x580FU 585 | #define OV5640_GMTRX24 0x5810U 586 | #define OV5640_GMTRX25 0x5811U 587 | #define OV5640_GMTRX30 0x5812U 588 | #define OV5640_GMTRX31 0x5813U 589 | #define OV5640_GMTRX32 0x5814U 590 | #define OV5640_GMTRX33 0x5815U 591 | #define OV5640_GMTRX34 0x5816U 592 | #define OV5640_GMTRX35 0x5817U 593 | #define OV5640_GMTRX40 0x5818U 594 | #define OV5640_GMTRX41 0x5819U 595 | #define OV5640_GMTRX42 0x581AU 596 | #define OV5640_GMTRX43 0x581BU 597 | #define OV5640_GMTRX44 0x581CU 598 | #define OV5640_GMTRX45 0x581DU 599 | #define OV5640_GMTRX50 0x581EU 600 | #define OV5640_GMTRX51 0x581FU 601 | #define OV5640_GMTRX52 0x5820U 602 | #define OV5640_GMTRX53 0x5821U 603 | #define OV5640_GMTRX54 0x5822U 604 | #define OV5640_GMTRX55 0x5823U 605 | #define OV5640_BRMATRX00 0x5824U 606 | #define OV5640_BRMATRX01 0x5825U 607 | #define OV5640_BRMATRX02 0x5826U 608 | #define OV5640_BRMATRX03 0x5827U 609 | #define OV5640_BRMATRX04 0x5828U 610 | #define OV5640_BRMATRX05 0x5829U 611 | #define OV5640_BRMATRX06 0x582AU 612 | #define OV5640_BRMATRX07 0x582BU 613 | #define OV5640_BRMATRX08 0x582CU 614 | #define OV5640_BRMATRX09 0x582DU 615 | #define OV5640_BRMATRX20 0x582EU 616 | #define OV5640_BRMATRX21 0x582FU 617 | #define OV5640_BRMATRX22 0x5830U 618 | #define OV5640_BRMATRX23 0x5831U 619 | #define OV5640_BRMATRX24 0x5832U 620 | #define OV5640_BRMATRX30 0x5833U 621 | #define OV5640_BRMATRX31 0x5834U 622 | #define OV5640_BRMATRX32 0x5835U 623 | #define OV5640_BRMATRX33 0x5836U 624 | #define OV5640_BRMATRX34 0x5837U 625 | #define OV5640_BRMATRX40 0x5838U 626 | #define OV5640_BRMATRX41 0x5839U 627 | #define OV5640_BRMATRX42 0x583AU 628 | #define OV5640_BRMATRX43 0x583BU 629 | #define OV5640_BRMATRX44 0x583CU 630 | #define OV5640_LENC_BR_OFFSET 0x583DU 631 | #define OV5640_MAX_GAIN 0x583EU 632 | #define OV5640_MIN_GAIN 0x583FU 633 | #define OV5640_MIN_Q 0x5840U 634 | #define OV5640_LENC_CTRL59 0x5841U 635 | #define OV5640_BR_HSCALE_HIGH 0x5842U 636 | #define OV5640_BR_HSCALE_LOW 0x5843U 637 | #define OV5640_BR_VSCALE_HIGH 0x5844U 638 | #define OV5640_BR_VSCALE_LOW 0x5845U 639 | #define OV5640_G_HSCALE_HIGH 0x5846U 640 | #define OV5640_G_HSCALE_LOW 0x5847U 641 | #define OV5640_G_VSCALE_HIGH 0x5848U 642 | #define OV5640_G_VSCALE_LOW 0x5849U 643 | 644 | /* AFC control [0x6000 ~ 0x603F] */ 645 | #define OV5640_AFC_CTRL00 0x6000U 646 | #define OV5640_AFC_CTRL01 0x6001U 647 | #define OV5640_AFC_CTRL02 0x6002U 648 | #define OV5640_AFC_CTRL03 0x6003U 649 | #define OV5640_AFC_CTRL04 0x6004U 650 | #define OV5640_AFC_CTRL05 0x6005U 651 | #define OV5640_AFC_CTRL06 0x6006U 652 | #define OV5640_AFC_CTRL07 0x6007U 653 | #define OV5640_AFC_CTRL08 0x6008U 654 | #define OV5640_AFC_CTRL09 0x6009U 655 | #define OV5640_AFC_CTRL10 0x600AU 656 | #define OV5640_AFC_CTRL11 0x600BU 657 | #define OV5640_AFC_CTRL12 0x600CU 658 | #define OV5640_AFC_CTRL13 0x600DU 659 | #define OV5640_AFC_CTRL14 0x600EU 660 | #define OV5640_AFC_CTRL15 0x600FU 661 | #define OV5640_AFC_CTRL16 0x6010U 662 | #define OV5640_AFC_CTRL17 0x6011U 663 | #define OV5640_AFC_CTRL18 0x6012U 664 | #define OV5640_AFC_CTRL19 0x6013U 665 | #define OV5640_AFC_CTRL20 0x6014U 666 | #define OV5640_AFC_CTRL21 0x6015U 667 | #define OV5640_AFC_CTRL22 0x6016U 668 | #define OV5640_AFC_CTRL23 0x6017U 669 | #define OV5640_AFC_CTRL24 0x6018U 670 | #define OV5640_AFC_CTRL25 0x6019U 671 | #define OV5640_AFC_CTRL26 0x601AU 672 | #define OV5640_AFC_CTRL27 0x601BU 673 | #define OV5640_AFC_CTRL28 0x601CU 674 | #define OV5640_AFC_CTRL29 0x601DU 675 | #define OV5640_AFC_CTRL30 0x601EU 676 | #define OV5640_AFC_CTRL31 0x601FU 677 | #define OV5640_AFC_CTRL32 0x6020U 678 | #define OV5640_AFC_CTRL33 0x6021U 679 | #define OV5640_AFC_CTRL34 0x6022U 680 | #define OV5640_AFC_CTRL35 0x6023U 681 | #define OV5640_AFC_CTRL36 0x6024U 682 | #define OV5640_AFC_CTRL37 0x6025U 683 | #define OV5640_AFC_CTRL38 0x6026U 684 | #define OV5640_AFC_CTRL39 0x6027U 685 | #define OV5640_AFC_CTRL40 0x6028U 686 | #define OV5640_AFC_CTRL41 0x6029U 687 | #define OV5640_AFC_CTRL42 0x602AU 688 | #define OV5640_AFC_CTRL43 0x602BU 689 | #define OV5640_AFC_CTRL44 0x602CU 690 | #define OV5640_AFC_CTRL45 0x602DU 691 | #define OV5640_AFC_CTRL46 0x602EU 692 | #define OV5640_AFC_CTRL47 0x602FU 693 | #define OV5640_AFC_CTRL48 0x6030U 694 | #define OV5640_AFC_CTRL49 0x6031U 695 | #define OV5640_AFC_CTRL50 0x6032U 696 | #define OV5640_AFC_CTRL51 0x6033U 697 | #define OV5640_AFC_CTRL52 0x6034U 698 | #define OV5640_AFC_CTRL53 0x6035U 699 | #define OV5640_AFC_CTRL54 0x6036U 700 | #define OV5640_AFC_CTRL55 0x6037U 701 | #define OV5640_AFC_CTRL56 0x6038U 702 | #define OV5640_AFC_CTRL57 0x6039U 703 | #define OV5640_AFC_CTRL58 0x603AU 704 | #define OV5640_AFC_CTRL59 0x603BU 705 | #define OV5640_AFC_CTRL60 0x603CU 706 | #define OV5640_AFC_READ58 0x603DU 707 | #define OV5640_AFC_READ59 0x603EU 708 | #define OV5640_AFC_READ60 0x603FU 709 | 710 | /** 711 | * @} 712 | */ 713 | 714 | /************** Generic Function *******************/ 715 | 716 | typedef int32_t (*OV5640_Write_Func)(void *, uint16_t, uint8_t *, uint16_t); 717 | typedef int32_t (*OV5640_Read_Func)(void *, uint16_t, uint8_t *, uint16_t); 718 | 719 | typedef struct 720 | { 721 | OV5640_Write_Func WriteReg; 722 | OV5640_Read_Func ReadReg; 723 | void *handle; 724 | } ov5640_ctx_t; 725 | 726 | /******************************************************************************* 727 | * Register : Generic - All 728 | * Address : Generic - All 729 | * Bit Group Name: None 730 | * Permission : W 731 | *******************************************************************************/ 732 | int32_t ov5640_write_reg(ov5640_ctx_t *ctx, uint16_t reg, uint8_t *pdata, uint16_t length); 733 | int32_t ov5640_read_reg(ov5640_ctx_t *ctx, uint16_t reg, uint8_t *pdata, uint16_t length); 734 | 735 | int32_t ov5640_register_set(ov5640_ctx_t *ctx, uint16_t reg, uint8_t value); 736 | int32_t ov5640_register_get(ov5640_ctx_t *ctx, uint16_t reg, uint8_t *value); 737 | 738 | 739 | /** 740 | * @} 741 | */ 742 | #ifdef __cplusplus 743 | } 744 | #endif 745 | 746 | #endif /* OV5640_REG_H */ 747 | /** 748 | * @} 749 | */ 750 | 751 | /** 752 | * @} 753 | */ 754 | 755 | /** 756 | * @} 757 | */ 758 | --------------------------------------------------------------------------------