Open FFBoard
Open source force feedback firmware
Loading...
Searching...
No Matches
I2C.cpp
Go to the documentation of this file.
1/*
2 * I2C.cpp
3 *
4 * Created on: 10.03.2022
5 * Author: Yannick
6 */
7
8#include <I2C.h>
9#ifdef I2CBUS
11 .name = "I2C port",
12 .id = CLSID_I2CPORT,
13 .visibility = ClassVisibility::visible};
14
15
16
17I2CPort::I2CPort(I2C_HandleTypeDef &hi2c,const I2CPortHardwareConfig& presets,uint8_t instance) : CommandHandler("i2c", CLSID_I2CPORT, instance), hi2c(hi2c),presets(presets) {
19#ifdef I2C_COMMANDS_DISABLED_IF_NOT_USED
20 this->setCommandsEnabled(false);
21#endif
23}
24
28
30 if(this->getCommandHandlerInfo()->instance != 0){
31 return; // Only first instance can save
32 }
33 uint16_t data = (this->speedPreset & 0b11); // 2 bits reserved. 1 used
34 Flash_Write(ADR_I2CCONF1, data);
35}
36
38 if(this->getCommandHandlerInfo()->instance != 0){
39 return; // Only first instance can save
40 }
41 uint16_t data;
42 if(Flash_Read(ADR_I2CCONF1, &data)){
43 setSpeedPreset(data & 0b11);
44 }
45}
46
47void I2CPort::setSpeedPreset(uint8_t preset){
48
49 speedPreset = std::min<uint8_t>(preset,presets.presets.size());
50 config = presets.getPreset(speedPreset).init;
51
52 if(portUsers)
54}
55
57 return speedPreset;
58}
59
62 registerCommand("speed", I2CPort_commands::speed, "I2C speed preset", CMDFLAG_GET|CMDFLAG_SET|CMDFLAG_INFOSTRING);
63}
64
65CommandStatus I2CPort::command(const ParsedCommand& cmd,std::vector<CommandReply>& replies){
66
67 switch(static_cast<I2CPort_commands>(cmd.cmdId)){
68
70 if(cmd.type == CMDtype::get){
71 replies.emplace_back(this->speedPreset);
72 }else if(cmd.type == CMDtype::set && presets.canChangeSpeed){
74 }else if(cmd.type == CMDtype::info){
75 for(uint8_t i = 0; i<presets.presets.size();i++){
76 replies.emplace_back(std::string(presets.presets[i].name) + ":" + std::to_string(i));
77 }
78 }
79 break;
80
81 default:
83 }
84 return CommandStatus::OK;
85}
86
94
100 if(portUsers++ == 0){
101 this->config = hi2c.Init;
102 //configurePort(&this->config);
103 setSpeedPreset(speedPreset); // Load speed and activate
104#ifdef I2C_COMMANDS_DISABLED_IF_NOT_USED
105 this->setCommandsEnabled(true);
106#endif
107 }
108}
109
115 if(portUsers>0){
116 portUsers--;
117 }
118 if(device == currentDevice){
119 currentDevice = nullptr; // invalidate pointer if a transfer was in progress
121 }
122 if(portUsers == 0){
123
124 HAL_I2C_DeInit(&hi2c);
125#ifdef I2C_COMMANDS_DISABLED_IF_NOT_USED
126 this->setCommandsEnabled(false);
127#endif
128 }
129
130}
131
132void I2CPort::configurePort(I2C_InitTypeDef* config){
133 if(config == nullptr){
134 return; // No need to reconfigure
135 }
136 this->config = *config;
137 hi2c.Init = this->config;
138 HAL_I2C_Init(&hi2c);
139}
140
141bool I2CPort::transmitMaster(I2CDevice* device,const uint16_t addr,uint8_t* pData,const uint16_t size,const uint32_t timeout,bool shiftAddr){
142 currentDevice = device;
143 device->startI2CTransfer(this);
144 bool flag = HAL_I2C_Master_Transmit(&this->hi2c, shiftAddr ? addr << 1 : addr, pData, size, timeout) == HAL_OK;
145 device->endI2CTransfer(this);
146 return flag;
147}
148
149bool I2CPort::transmitMasterDMA(I2CDevice* device,const uint16_t addr,uint8_t* pData,const uint16_t size,bool shiftAddr){
150 currentDevice = device;
151 device->startI2CTransfer(this);
152 return HAL_I2C_Master_Transmit_DMA(&this->hi2c, shiftAddr ? addr << 1 : addr, pData, size) == HAL_OK;
153}
154
155bool I2CPort::transmitMasterIT(I2CDevice* device,const uint16_t addr,uint8_t* pData,const uint16_t size,bool shiftAddr){
156 currentDevice = device;
157 device->startI2CTransfer(this);
158 return HAL_I2C_Master_Transmit_IT(&this->hi2c, shiftAddr ? addr << 1 : addr, pData, size) == HAL_OK;
159}
160
161bool I2CPort::receiveMaster(I2CDevice* device,const uint16_t addr,uint8_t* pData,const uint16_t size,const uint32_t timeout,bool shiftAddr){
162 currentDevice = device;
163 device->startI2CTransfer(this);
164 bool flag = HAL_I2C_Master_Receive(&this->hi2c, shiftAddr ? addr << 1 : addr, pData, size, timeout) == HAL_OK;
165 device->endI2CTransfer(this);
166 return flag;
167}
168
169bool I2CPort::receiveMasterDMA(I2CDevice* device,const uint16_t addr,uint8_t* pData,const uint16_t size,bool shiftAddr){
170 currentDevice = device;
171 device->startI2CTransfer(this);
172 return HAL_I2C_Master_Receive_DMA(&this->hi2c, shiftAddr ? addr << 1 : addr, pData, size) == HAL_OK;
173}
174
175bool I2CPort::receiveMasterIT(I2CDevice* device,const uint16_t addr,uint8_t* pData,const uint16_t size,bool shiftAddr){
176 currentDevice = device;
177 device->startI2CTransfer(this);
178 return HAL_I2C_Master_Receive_IT(&this->hi2c, shiftAddr ? addr << 1 : addr, pData, size) == HAL_OK;
179}
180
181
182bool I2CPort::writeMem(I2CDevice* device,const uint16_t devAddr,const uint16_t memAddr,const uint16_t memAddSize,uint8_t* pData,const uint16_t size,const uint32_t timeout,bool shiftAddr){
183 currentDevice = device;
184 device->startI2CTransfer(this);
185 bool flag = HAL_I2C_Mem_Write(&this->hi2c, shiftAddr ? devAddr << 1 : devAddr, memAddr, memAddSize, pData, size, timeout) == HAL_OK;
186 device->endI2CTransfer(this);
187 return flag;
188}
189
190bool I2CPort::readMem(I2CDevice* device,const uint16_t devAddr,const uint16_t memAddr,const uint16_t memAddSize,uint8_t* pData,const uint16_t size,const uint32_t timeout,bool shiftAddr){
191 currentDevice = device;
192 device->startI2CTransfer(this);
193 bool flag = HAL_I2C_Mem_Read(&this->hi2c, shiftAddr ? devAddr << 1 : devAddr, memAddr, memAddSize, pData, size, timeout) == HAL_OK;
194 device->endI2CTransfer(this);
195 return flag;
196}
197
198bool I2CPort::readMemIT(I2CDevice* device,const uint16_t devAddr,const uint16_t memAddr,const uint16_t memAddSize,uint8_t* pData,const uint16_t size,bool shiftAddr){
199 currentDevice = device;
200 device->startI2CTransfer(this);
201 bool flag = HAL_I2C_Mem_Read_IT(&this->hi2c, shiftAddr ? devAddr << 1 : devAddr, memAddr, memAddSize, pData, size) == HAL_OK;
202 //device->endI2CTransfer(this);
203 return flag;
204}
205
206bool I2CPort::writeMemIT(I2CDevice* device,const uint16_t devAddr,const uint16_t memAddr,const uint16_t memAddSize,uint8_t* pData,const uint16_t size,bool shiftAddr){
207 currentDevice = device;
208 device->startI2CTransfer(this);
209 bool flag = HAL_I2C_Mem_Write_IT(&this->hi2c, shiftAddr ? devAddr << 1 : devAddr, memAddr, memAddSize, pData, size) == HAL_OK;
210 //device->endI2CTransfer(this);
211 return flag;
212}
213
214bool I2CPort::isDeviceReady(I2CDevice* device,const uint16_t devAddr,const uint32_t trials,uint32_t timeout,bool shiftAddr){
215 currentDevice = device;
216 device->startI2CTransfer(this);
217 bool flag = HAL_I2C_IsDeviceReady(&this->hi2c, shiftAddr ? devAddr << 1 : devAddr, trials,timeout) == HAL_OK;
218 device->endI2CTransfer(this);
219 return flag;
220}
221
222void I2CPort::I2cTxCplt(I2C_HandleTypeDef *hi2c){
223 if (currentDevice == nullptr) {
224 return;
225 }
226
227 if (hi2c->Instance != this->hi2c.Instance) {
228 return;
229 }
230 currentDevice->endI2CTransfer(this);
231 currentDevice->i2cTxCompleted(this);
232
233 currentDevice = nullptr;
234}
235
236void I2CPort::I2cRxCplt(I2C_HandleTypeDef *hi2c){
237 if (currentDevice == nullptr) {
238 return;
239 }
240
241 if (hi2c->Instance != this->hi2c.Instance) {
242 return;
243 }
244 currentDevice->endI2CTransfer(this);
245 currentDevice->i2cRxCompleted(this);
246
247 currentDevice = nullptr;
248}
249
250void I2CPort::I2cError(I2C_HandleTypeDef *hi2c){
251 if (currentDevice){
252 currentDevice->i2cError(this);
253 }else{
254 resetPort();
255 }
256}
257
259 return hi2c.State != HAL_I2C_STATE_READY;
260}
261
263 bool isIsr = inIsr();
264
265 if(isIsr){
266 BaseType_t taskWoken = 0;
267 this->semaphore.TakeFromISR(&taskWoken);
268 portYIELD_FROM_ISR(taskWoken);
269 }else{
270 this->semaphore.Take();
271 }
272 //isTakenFlag = true;
273}
274
276 bool isIsr = inIsr();
277 //isTakenFlag = false;
278 if(isIsr){
279 BaseType_t taskWoken = 0;
280 this->semaphore.GiveFromISR(&taskWoken);
281 portYIELD_FROM_ISR(taskWoken);
282 }else{
283 this->semaphore.Give();
284 }
285
286}
287
294
296 port->takeSemaphore();
297}
298
300 port->giveSemaphore();
301}
302
303
305
306}
308
309}
311 port->resetPort();
312}
313#endif
CommandStatus
void registerCommand(const char *cmd, const ID cmdid, const char *help=nullptr, uint32_t flags=0)
virtual void setCommandsEnabled(bool enable)
virtual CmdHandlerInfo * getCommandHandlerInfo()
CommandHandler(const char *clsname, uint16_t clsid, uint8_t instance=0)
virtual void i2cError(I2CPort *port)
Definition I2C.cpp:310
virtual void i2cTxCompleted(I2CPort *port)
Definition I2C.cpp:304
virtual void i2cRxCompleted(I2CPort *port)
Definition I2C.cpp:307
virtual void startI2CTransfer(I2CPort *port)
Definition I2C.cpp:295
virtual ~I2CDevice()
Definition I2C.cpp:291
I2CDevice()
Definition I2C.cpp:288
virtual void endI2CTransfer(I2CPort *port)
Definition I2C.cpp:299
Definition I2C.h:43
bool writeMemIT(I2CDevice *device, const uint16_t devAddr, const uint16_t memAddr, const uint16_t memAddSize, uint8_t *pData, const uint16_t size, bool shiftAddr=true)
Definition I2C.cpp:206
uint8_t speedPreset
Definition I2C.h:100
cpp_freertos::BinarySemaphore semaphore
Definition I2C.h:95
CommandStatus command(const ParsedCommand &cmd, std::vector< CommandReply > &replies)
Definition I2C.cpp:65
void registerCommands()
Definition I2C.cpp:60
const I2CPortHardwareConfig & presets
Definition I2C.h:102
virtual ~I2CPort()
Definition I2C.cpp:25
void I2cError(I2C_HandleTypeDef *hi2c)
Definition I2C.cpp:250
void takeSemaphore()
Definition I2C.cpp:262
bool isDeviceReady(I2CDevice *device, const uint16_t devAddr, const uint32_t trials, uint32_t timeout, bool shiftAddr=true)
Definition I2C.cpp:214
I2C_HandleTypeDef & hi2c
Definition I2C.h:97
bool transmitMasterDMA(I2CDevice *device, const uint16_t addr, uint8_t *pData, const uint16_t size, bool shiftAddr=true)
Definition I2C.cpp:149
void giveSemaphore()
Definition I2C.cpp:275
bool receiveMasterIT(I2CDevice *device, const uint16_t addr, uint8_t *pData, const uint16_t size, bool shiftAddr=true)
Definition I2C.cpp:175
bool receiveMaster(I2CDevice *device, const uint16_t addr, uint8_t *pData, const uint16_t size, const uint32_t timeout, bool shiftAddr=true)
Definition I2C.cpp:161
void restoreFlash()
Definition I2C.cpp:37
int32_t portUsers
Definition I2C.h:99
bool transmitMaster(I2CDevice *device, const uint16_t addr, uint8_t *pData, const uint16_t size, const uint32_t timeout, bool shiftAddr=true)
Definition I2C.cpp:141
bool readMem(I2CDevice *device, const uint16_t devAddr, const uint16_t memAddr, const uint16_t memAddSize, uint8_t *pData, const uint16_t size, const uint32_t timeout, bool shiftAddr=true)
Definition I2C.cpp:190
void freePort(I2CDevice *device)
Definition I2C.cpp:114
bool readMemIT(I2CDevice *device, const uint16_t devAddr, const uint16_t memAddr, const uint16_t memAddSize, uint8_t *pData, const uint16_t size, bool shiftAddr=true)
Definition I2C.cpp:198
I2CPort(I2C_HandleTypeDef &hi2c, const I2CPortHardwareConfig &presets, uint8_t instance=0)
Definition I2C.cpp:17
I2C_InitTypeDef config
Definition I2C.h:101
void saveFlash()
Definition I2C.cpp:29
void I2cTxCplt(I2C_HandleTypeDef *hi2c)
Definition I2C.cpp:222
void takePort(I2CDevice *device)
Definition I2C.cpp:99
void I2cRxCplt(I2C_HandleTypeDef *hi2c)
Definition I2C.cpp:236
static ClassIdentifier info
Definition I2C.h:10
bool writeMem(I2CDevice *device, const uint16_t devAddr, const uint16_t memAddr, const uint16_t memAddSize, uint8_t *pData, const uint16_t size, const uint32_t timeout, bool shiftAddr=true)
Definition I2C.cpp:182
void configurePort(I2C_InitTypeDef *config)
Definition I2C.cpp:132
void resetPort()
Definition I2C.cpp:90
void setSpeedPreset(uint8_t preset)
Definition I2C.cpp:47
bool receiveMasterDMA(I2CDevice *device, const uint16_t addr, uint8_t *pData, const uint16_t size, bool shiftAddr=true)
Definition I2C.cpp:169
I2CDevice * currentDevice
Definition I2C.h:98
bool transmitMasterIT(I2CDevice *device, const uint16_t addr, uint8_t *pData, const uint16_t size, bool shiftAddr=true)
Definition I2C.cpp:155
I2CPort_commands
Definition I2C.h:44
uint8_t getSpeedPreset()
Definition I2C.cpp:56
bool isTaken()
Definition I2C.cpp:258
static bool inIsr()
Definition cppmain.h:41
static struct @024127060247016123033304002117326322243354210111 data
bool Flash_Write(uint16_t adr, uint16_t dat)
bool Flash_Read(uint16_t adr, uint16_t *buf, bool checkempty=true)