Fix doc path
[opentx.git] / radio / src / targets / taranis / i2c_driver.cpp
blob65138b7eba0627552b632dcda354f23682866b0e
1 /*
2 * Copyright (C) OpenTX
4 * Based on code named
5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #include "board.h"
23 void eepromPageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite);
24 void eepromWaitEepromStandbyState(void);
26 void i2cInit()
28 I2C_DeInit(I2C);
30 GPIO_InitTypeDef GPIO_InitStructure;
31 GPIO_InitStructure.GPIO_Pin = I2C_WP_GPIO_PIN;
32 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
33 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
34 GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
35 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
36 GPIO_Init(I2C_WP_GPIO, &GPIO_InitStructure);
37 GPIO_ResetBits(I2C_WP_GPIO, I2C_WP_GPIO_PIN);
39 I2C_InitTypeDef I2C_InitStructure;
40 I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED;
41 I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
42 I2C_InitStructure.I2C_OwnAddress1 = 0x00;
43 I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
44 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
45 I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
46 I2C_Init(I2C, &I2C_InitStructure);
47 I2C_Cmd(I2C, ENABLE);
49 GPIO_PinAFConfig(I2C_SPI_GPIO, I2C_SCL_GPIO_PinSource, I2C_GPIO_AF);
50 GPIO_PinAFConfig(I2C_SPI_GPIO, I2C_SDA_GPIO_PinSource, I2C_GPIO_AF);
52 GPIO_InitStructure.GPIO_Pin = I2C_SCL_GPIO_PIN | I2C_SDA_GPIO_PIN;
53 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
54 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
55 GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
56 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
57 GPIO_Init(I2C_SPI_GPIO, &GPIO_InitStructure);
60 #define I2C_TIMEOUT_MAX 1000
61 bool I2C_WaitEvent(uint32_t event)
63 uint32_t timeout = I2C_TIMEOUT_MAX;
64 while (!I2C_CheckEvent(I2C, event)) {
65 if ((timeout--) == 0) return false;
67 return true;
70 bool I2C_WaitEventCleared(uint32_t event)
72 uint32_t timeout = I2C_TIMEOUT_MAX;
73 while (I2C_CheckEvent(I2C, event)) {
74 if ((timeout--) == 0) return false;
76 return true;
79 /**
80 * @brief Reads a block of data from the EEPROM.
81 * @param pBuffer : pointer to the buffer that receives the data read
82 * from the EEPROM.
83 * @param ReadAddr : EEPROM's internal address to read from.
84 * @param NumByteToRead : number of bytes to read from the EEPROM.
85 * @retval None
87 bool I2C_EE_ReadBlock(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t NumByteToRead)
89 if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
90 return false;
92 I2C_GenerateSTART(I2C, ENABLE);
93 if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
94 return false;
96 I2C_Send7bitAddress(I2C, I2C_ADDRESS_EEPROM, I2C_Direction_Transmitter);
97 if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
98 return false;
100 I2C_SendData(I2C, (uint8_t)((ReadAddr & 0xFF00) >> 8));
101 if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
102 return false;
103 I2C_SendData(I2C, (uint8_t)(ReadAddr & 0x00FF));
104 if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
105 return false;
107 I2C_GenerateSTART(I2C, ENABLE);
108 if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
109 return false;
111 I2C_Send7bitAddress(I2C, I2C_ADDRESS_EEPROM, I2C_Direction_Receiver);
112 if (!I2C_WaitEvent(I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
113 return false;
115 if (NumByteToRead > 1) {
116 I2C_AcknowledgeConfig(I2C, ENABLE);
119 while (NumByteToRead) {
120 if (NumByteToRead == 1) {
121 I2C_AcknowledgeConfig(I2C, DISABLE);
123 if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_RECEIVED))
124 return false;
125 *pBuffer++ = I2C_ReceiveData(I2C);
126 NumByteToRead--;
129 I2C_GenerateSTOP(I2C, ENABLE);
130 return true;
133 void eepromReadBlock(uint8_t * buffer, size_t address, size_t size)
135 while (!I2C_EE_ReadBlock(buffer, address, size)) {
136 i2cInit();
141 * @brief Writes buffer of data to the I2C EEPROM.
142 * @param buffer : pointer to the buffer containing the data to be
143 * written to the EEPROM.
144 * @param address : EEPROM's internal address to write to.
145 * @param size : number of bytes to write to the EEPROM.
146 * @retval None
148 void eepromWriteBlock(uint8_t * buffer, size_t address, size_t size)
150 uint8_t offset = address % I2C_FLASH_PAGESIZE;
151 uint8_t count = I2C_FLASH_PAGESIZE - offset;
152 if (size < count) {
153 count = size;
155 while (count > 0) {
156 eepromPageWrite(buffer, address, count);
157 eepromWaitEepromStandbyState();
158 address += count;
159 buffer += count;
160 size -= count;
161 count = I2C_FLASH_PAGESIZE;
162 if (size < I2C_FLASH_PAGESIZE) {
163 count = size;
168 uint8_t eepromIsTransferComplete()
170 return 1;
174 * @brief Writes more than one byte to the EEPROM with a single WRITE cycle.
175 * @note The number of byte can't exceed the EEPROM page size.
176 * @param pBuffer : pointer to the buffer containing the data to be
177 * written to the EEPROM.
178 * @param WriteAddr : EEPROM's internal address to write to.
179 * @param NumByteToWrite : number of bytes to write to the EEPROM.
180 * @retval None
182 bool I2C_EE_PageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite)
184 if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
185 return false;
187 I2C_GenerateSTART(I2C, ENABLE);
188 if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
189 return false;
191 I2C_Send7bitAddress(I2C, I2C_ADDRESS_EEPROM, I2C_Direction_Transmitter);
192 if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
193 return false;
195 I2C_SendData(I2C, (uint8_t)((WriteAddr & 0xFF00) >> 8));
196 if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
197 return false;
198 I2C_SendData(I2C, (uint8_t)(WriteAddr & 0x00FF));
199 if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
200 return false;
202 /* While there is data to be written */
203 while (NumByteToWrite--) {
204 I2C_SendData(I2C, *pBuffer);
205 if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
206 return false;
207 pBuffer++;
210 if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
211 return false;
213 I2C_GenerateSTOP(I2C, ENABLE);
214 return true;
217 void eepromPageWrite(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t NumByteToWrite)
219 while (!I2C_EE_PageWrite(pBuffer, WriteAddr, NumByteToWrite)) {
220 i2cInit();
225 * @brief Wait for EEPROM Standby state
226 * @param None
227 * @retval None
229 bool I2C_EE_WaitEepromStandbyState(void)
231 do {
232 I2C_GenerateSTART(I2C, ENABLE);
233 if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
234 return false;
236 I2C_Send7bitAddress(I2C, I2C_ADDRESS_EEPROM, I2C_Direction_Transmitter);
237 } while (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
239 I2C_GenerateSTOP(I2C, ENABLE);
240 return true;
243 void eepromWaitEepromStandbyState(void)
245 while (!I2C_EE_WaitEepromStandbyState()) {
246 i2cInit();
250 #if !defined(BOOT) && !defined(SOFTWARE_VOLUME)
251 const uint8_t volumeScale[VOLUME_LEVEL_MAX+1] = {
252 0, 1, 2, 3, 5, 9, 13, 17, 22, 27, 33, 40,
253 64, 82, 96, 105, 112, 117, 120, 122, 124, 125, 126, 127
256 void setScaledVolume(uint8_t volume)
258 if (volume > VOLUME_LEVEL_MAX) {
259 volume = VOLUME_LEVEL_MAX;
262 setVolume(volumeScale[volume]);
265 void setVolume(uint8_t volume)
267 if (!I2C_WaitEventCleared(I2C_FLAG_BUSY))
268 return;
270 I2C_GenerateSTART(I2C, ENABLE);
271 if (!I2C_WaitEvent(I2C_EVENT_MASTER_MODE_SELECT))
272 return;
274 I2C_Send7bitAddress(I2C, I2C_ADDRESS_VOLUME, I2C_Direction_Transmitter);
275 if (!I2C_WaitEvent(I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
276 return;
278 I2C_SendData(I2C, 0);
279 if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTING))
280 return;
281 I2C_SendData(I2C, volume);
282 if (!I2C_WaitEvent(I2C_EVENT_MASTER_BYTE_TRANSMITTED))
283 return;
285 I2C_GenerateSTOP(I2C, ENABLE);
288 int32_t getVolume()
290 return -1; // TODO
292 #endif