Open FFBoard
Open source force feedback firmware
Loading...
Searching...
No Matches
ADS111X.cpp
Go to the documentation of this file.
1/*
2 * ADS111X.cpp
3 *
4 * Created on: 21.04.2022
5 * Author: Yannick
6 */
7
8#include "ADS111X.h"
9#ifdef I2C_PORT
11 port.takePort(this);
12}
13
15 port.freePort(this);
16}
17
18
19void ADS111X::readRegIT(const uint8_t reg,uint16_t* data){
20 port.takeSemaphore();
21 port.readMemIT(this, address, reg, 1, (uint8_t*)data, 2);
22}
23
24uint16_t ADS111X::readReg(const uint8_t reg){
25 uint16_t buf=0;
26 port.takeSemaphore();
27 port.readMem(this, address, reg, 1, (uint8_t*)&buf, 2,100);
28 return buf;
29}
30
31void ADS111X::writeRegIT(const uint8_t reg,uint16_t data){
32 writeItBuffer = __REV16(data);
33 port.takeSemaphore();
34
35 port.writeMemIT(this, address, reg, 1, (uint8_t*)&writeItBuffer, 2);
36}
37
38void ADS111X::writeReg(const uint8_t reg,uint16_t data){
39 writeItBuffer = __REV16(data);
40 port.takeSemaphore();
41 port.writeMem(this, address, reg, 1, (uint8_t*)&writeItBuffer, 2,100);
42}
43
44void ADS111X::setThresh(uint16_t lowTh, uint16_t highTh){
45 registers.lothresh = lowTh;
46 registers.hithresh = highTh;
47 writeRegIT(0x02, registers.lothresh);
48 writeRegIT(0x03, registers.hithresh);
49}
50
60void ADS111X::setGain(uint16_t gain){
61 this->gain = clip<uint16_t,uint16_t>(gain, 0, 5);
62// this->registers.config &= ~0x0E00;
63// this->registers.config |= this->gain << 9;
64// writeRegIT(0x01, this->registers.config);
65}
66
67
79void ADS111X::setDatarate(uint16_t rate){
81}
82
83
98void ADS111X::startConversion(uint8_t channel, bool differential){
99 uint16_t mux = 0;
100 if(differential){
101 switch(channel)
102 {
103 default:
104 case 0:
105 mux = 0x0000;
106 break;
107 case 1:
108 mux = 0x3000;
109 break;
110 case 2:
111 mux = 0x1000;
112 break;
113 case 3:
114 mux = 0x2000;
115 break;
116
117 }
118 }else{
119 switch(channel)
120 {
121 default:
122 case 0:
123 mux = 0x4000;
124 break;
125 case 1:
126 mux = 0x5000;
127 break;
128 case 2:
129 mux = 0x6000;
130 break;
131 case 3:
132 mux = 0x7000;
133 break;
134
135 }
136 }
137 this->registers.config = 0x103; // Default settings. Single conversion 103
138 this->registers.config |= mux;
139 this->registers.config |= 0x8000; // Start conversion
140 this->registers.config |= datarate << 5; // Read datarate from separate variable to make sure it is updated if connection was interrupted
141 this->registers.config |= gain << 9;
142 writeRegIT(0x01, this->registers.config);
143}
144
145
146
148 //port->takeSemaphore(); // Take semaphore before setting buffers
149}
150
152 port->giveSemaphore(); // Take semaphore before setting buffers
153}
154
155
156
157
158// ---------------------------------------------------------------------- //
159#ifdef ADS111XANALOG
161 .name = "ADS111X ADC" ,
162 .id=CLSID_ANALOG_ADS111X,
163 };
167
168
169const std::array<std::pair<uint16_t,uint16_t>,4> minMaxValAddr = {
170 std::pair<uint16_t,uint16_t>(ADR_ADS111X_MIN_0,ADR_ADS111X_MAX_0),
171 std::pair<uint16_t,uint16_t>(ADR_ADS111X_MIN_1,ADR_ADS111X_MAX_1),
172 std::pair<uint16_t,uint16_t>(ADR_ADS111X_MIN_2,ADR_ADS111X_MAX_2),
173 std::pair<uint16_t,uint16_t>(ADR_ADS111X_MIN_3,ADR_ADS111X_MAX_3),
174
175};
176
177ADS111X_AnalogSource::ADS111X_AnalogSource() : ADS111X(i2cport) , CommandHandler("adsAnalog", CLSID_ANALOG_ADS111X, 0),AnalogAxisProcessing(4,this,this, true,true,true,true), Thread("ads111x", 64, 25) {
180 registerCommand("inputs", ADS111X_AnalogSource_commands::axes, "Amount of inputs (1-4 or 1-2 if differential)",CMDFLAG_GET | CMDFLAG_SET);
181 //registerCommand("addr", ADS111X_AnalogSource_commands::address, "Address",CMDFLAG_GET | CMDFLAG_SET);
182 registerCommand("diff", ADS111X_AnalogSource_commands::differential, "Differential mode (Ch0= 0p 1n Ch1= 2p 3n)",CMDFLAG_GET | CMDFLAG_SET);
183 registerCommand("gain", ADS111X_AnalogSource_commands::gain, "PGA scale (0-5)",CMDFLAG_GET | CMDFLAG_SET | CMDFLAG_INFOSTRING);
184 registerCommand("rate", ADS111X_AnalogSource_commands::rate, "Data rate (0-7)",CMDFLAG_GET | CMDFLAG_SET | CMDFLAG_INFOSTRING);
185 restoreFlash();
186 this->Start();
187}
188
192
202
213
215 // Must not be called in constructor
216 //setThresh(0,0x8000);
217 lastSuccess = HAL_GetTick();
218 port.resetPort();
219 lastAxis = 0;
221}
222
227
228// Handles starting next transfer for >1 byte transfers
230 while(true){
231
232
233 /*
234 * Sequence:
235 * Start sampling at channel 0
236 * Wait until request done
237 * Poll if sampling is done
238 * Wait until request done and possibly repeat polling
239 * Read sample and store in buffer when request done
240 *
241 */
242
244 initialize();
245 }
246
248
250 // Next transfer
252 ADS111X::startConversion(lastAxis,differentialMode); // Change channel and sample
253
255 // Check if done
256 Delay(1); // Sampling takes at least 1ms so we sleep before polling
258
260
261 // if done read sample
263 ADS111X::readRegIT(0x00, (uint16_t*)&sampleBuffer); // Read last conversion
264 }
265
266 }else{
267 // Last conversion done. store in buffer
268 lastAxis = 0;
269 lastSuccess = HAL_GetTick();
270
272
273 }
274 }
275}
276
281 if(port != &this->port || state == ADS111X_AnalogSource_state::idle){
282 return;
283 }
285 // Check config reg if conversion is done yet
286 configRegBuf = __REV16(configRegBuf);
287 if((configRegBuf & 0x8000) != 0){
288 // Done
290 }
292 sampleBuffer = __REV16(sampleBuffer); // Reverse buffer
293 if(!differentialMode){
294 sampleBuffer = (clip<int16_t,int16_t>(sampleBuffer,0,0x7fff) - 0x3fff) * 2 - 1; // Shift because we can't go below GND anyways
295 }
296 rawbuf[lastAxis] = (int16_t)sampleBuffer;
297 lastAxis++;
298 state = ADS111X_AnalogSource_state::beginSampling; // Begin next sample or go idle
299 }
300
302}
303
307 if(port != &this->port || state == ADS111X_AnalogSource_state::idle){
308 return;
309 }
310
311 if(state == ADS111X_AnalogSource_state::beginSampling){ // Last command started the sampling and was sent out. We are now waiting
313 }
314
316}
317
318std::vector<int32_t>* ADS111X_AnalogSource::getAxes(){
319
320 if(state == ADS111X_AnalogSource_state::idle && !port.isTaken()){
321 //Begin transfer
322 lastAxis = 0;
324 Notify();
325 }
326
327 if(HAL_GetTick() - lastSuccess > 4000){
329 Notify();
330 }
331 buf = rawbuf;
332 AnalogAxisProcessing::processAxes(buf); // Do processing every call to keep filter samplerate steady
333 return &this->buf;
334}
335
338 this->axes = clip<uint16_t,uint16_t>(axes,1,differentialMode ? 2 : 4);
339 this->buf.resize(this->axes,0);
340 this->rawbuf.resize(this->axes,0);
341}
342
343CommandStatus ADS111X_AnalogSource::command(const ParsedCommand& cmd,std::vector<CommandReply>& replies){
344
345 switch(static_cast<ADS111X_AnalogSource_commands>(cmd.cmdId)){
346
348 if(cmd.type == CMDtype::set){
350 }else if(cmd.type == CMDtype::get){
351 replies.emplace_back(axes);
352 }
353 break;
354
356 if(cmd.type == CMDtype::set){
357 this->setGain(cmd.val);
358 }else if(cmd.type == CMDtype::get){
359 replies.emplace_back(gain);
360 }else if(cmd.type == CMDtype::info){
361 //replies.emplace_back("2/3x:0,1x:1,2x:2,4x:3,8x:4,16x:5");
362 replies.emplace_back("6.144V:0,4.096V:1,2.048V:2,1.024V:3,0.512V:4,0.256V:5");
363 }
364 break;
365
367 if(cmd.type == CMDtype::set){
368 setAxes(axes,cmd.val != 0); // Limit axes
369 }else if(cmd.type == CMDtype::get){
370 replies.emplace_back(differentialMode);
371 }
372 break;
373
375 if(cmd.type == CMDtype::set){
376 setDatarate(cmd.val);
377 }else if(cmd.type == CMDtype::get){
378 replies.emplace_back(datarate);
379 }else if(cmd.type == CMDtype::info){
380 replies.emplace_back("8 SPS:0,16 SPS:1,32 SPS:2,64 SPS:3,128 SPS:4,250 SPS:5,475 SPS:6,860 SPS:7");
381 }
382 break;
383 case ADS111X_AnalogSource_commands::address: // No option yet
384 default:
385 return AnalogAxisProcessing::command(cmd, replies); // Try processing command
386 }
387 return CommandStatus::OK;
388}
389#endif
390#endif
const std::array< std::pair< uint16_t, uint16_t >, 4 > minMaxValAddr
Definition ADS111X.cpp:169
CommandStatus
uint16_t configRegBuf
Definition ADS111X.h:101
void setAxes(uint8_t axes, bool differential)
Definition ADS111X.cpp:336
void i2cTxCompleted(I2CPort *port)
Definition ADS111X.cpp:306
static ClassIdentifier info
Definition ADS111X.h:160
std::vector< int32_t > rawbuf
Definition ADS111X.h:106
CommandStatus command(const ParsedCommand &cmd, std::vector< CommandReply > &replies)
Definition ADS111X.cpp:343
void i2cRxCompleted(I2CPort *port)
Definition ADS111X.cpp:280
void i2cError(I2CPort *port)
Definition ADS111X.cpp:223
uint32_t lastSuccess
Definition ADS111X.h:104
virtual const ClassIdentifier getInfo()
Definition ADS111X.cpp:164
std::vector< int32_t > * getAxes()
Definition ADS111X.cpp:318
volatile ADS111X_AnalogSource_state state
Definition ADS111X.h:107
void startI2CTransfer(I2CPort *port)
Definition ADS111X.cpp:147
uint8_t gain
Definition ADS111X.h:51
void setGain(uint16_t gain)
Definition ADS111X.cpp:60
virtual ~ADS111X()
Definition ADS111X.cpp:14
uint16_t writeItBuffer
Definition ADS111X.h:60
void endI2CTransfer(I2CPort *port)
Definition ADS111X.cpp:151
void writeReg(const uint8_t reg, uint16_t data)
Definition ADS111X.cpp:38
void writeRegIT(const uint8_t reg, uint16_t data)
Definition ADS111X.cpp:31
void setThresh(uint16_t loTh, uint16_t hiTh)
Definition ADS111X.cpp:44
ADS111X(I2CPort &port, uint8_t address=0x48)
Definition ADS111X.cpp:10
I2CPort & port
Definition ADS111X.h:46
uint8_t address
Definition ADS111X.h:49
void startConversion(uint8_t channel, bool differential=false)
Definition ADS111X.cpp:98
struct ADS111X::@012117373011170006276207023263276052355116021132 registers
uint16_t readReg(const uint8_t reg)
Definition ADS111X.cpp:24
void readRegIT(const uint8_t reg, uint16_t *data)
Definition ADS111X.cpp:19
void setDatarate(uint16_t rate)
Definition ADS111X.cpp:79
uint8_t datarate
Definition ADS111X.h:50
void saveMinMaxValues(const std::array< std::pair< uint16_t, uint16_t >, size > &minMaxAddresses)
AnalogAxisProcessing(const uint32_t axisAmount, AnalogSource *analogSource, CommandHandler *cmdHandler=nullptr, bool allowFilters=true, bool allowAutoscale=true, bool allowRawValues=false, bool allowManualScale=false)
void processAxes(std::vector< int32_t > &buf)
static AnalogProcessingConfig decodeAnalogProcessingConfFromInt(uint16_t val)
AnalogProcessingConfig & getAnalogProcessingConfig()
CommandStatus command(const ParsedCommand &cmd, std::vector< CommandReply > &replies)
void restoreMinMaxValues(const std::array< std::pair< uint16_t, uint16_t >, size > &minMaxAddresses)
static uint16_t encodeAnalogProcessingConfToInt(AnalogProcessingConfig &conf)
void setAnalogProcessingConfig(AnalogProcessingConfig conf)
std::vector< int32_t > buf
void registerCommand(const char *cmd, const ID cmdid, const char *help=nullptr, uint32_t flags=0)
CommandHandler(const char *clsname, uint16_t clsid, uint8_t instance=0)
Definition I2C.h:43
uint32_t WaitForNotification(TickType_t Timeout=portMAX_DELAY)
Definition thread.hpp:246
void Delay(const TickType_t Delay)
Definition thread.hpp:352
Thread(const std::string Name, uint16_t StackDepth, UBaseType_t Priority)
Definition cthread.cpp:56
I2CPort i2cport
T clip(T v, C l, C h)
Definition cppmain.h:58
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)