source: trunk/fw_g473rct/SES/src/ads1260.c@ 20

Last change on this file since 20 was 20, checked in by f.jahn, 4 months ago

adc dma funktioniert und modbus funktioniert

File size: 47.3 KB
Line 
1/******************************************************************************
2*
3* @file ads1260.c
4* @author ECS, Joseph Zimmer
5* @version V1.0.0
6* @date 25-04-2019
7* @brief
8* INITIALISIERUNG ADS1260:
9* 0. Setze die ADC Zustandsvariable auf ADC_STATE_INITIALIZE
10* PIN CONFIG:
11* 1. ADC_POWER_DOWN_Pin auf 1 setzen -> ADS power up
12* 2. ADC_RESET_Pin auf 1 setzen -> ADS reset Zustand abschalten
13* 3. ADC_START_CONV_Pin auf 0 setzen -> ADS in Konfigurationsmodus ADC läuft nicht
14*
15* WARTEN AUF:
16* 4. // warten bis ADC_DATA_READY_Pin auf 1 ist -> wenn auf 1 ist dann ist der Chip bereit für Kommunikation //
17* wurde ersetzt durch einschalten des Data Ready Interrupts dieser löst bei fallender Flanke aus
18* die fallende Flanke wird generiert durch den ADS1260 wenn dieser mit der Data Conversion fertig ist.
19*
20* REGISTER CONFIG:
21* 5. interne Referenzspannung 2.500V wird eingeschaltet, lässt sich mit ADC vom STM32G0 messen
22* 6. Samplerate auf 10 sps- setzen
23* 7. Filter auf FIR setzen
24* 8. Conversion Mode auf Mode Pulse setzen -> nur eine Conversion wenn gestartet muss für jede neue Conversion neu aufgerufen werden
25* 9. Schalte AIN0 und AIN1 auf dem ADC
26* 10. Self Offset Calibration wird durchgeführt
27*
28* x. Setze die ADC Zustandsvariable auf ADC_STATE_CONVERSION_STOPPED
29*
30*
31*
32*
33* REGISTER SCHREIBEN:
34*
35* 1.Byte 0x40 + Register Adresse || 2.Byte 0xXX Daten
36* Bsp:
37* Code 0x40 + Register 0x06, Daten 0x10
38* => 1.Byte 0x46, => 2.Byte 0x10
39*
40*
41*
42******************************************************************************/
43
44// --- INCLUDES -----------------------------------------------------------------
45#include "ads1260.h"
46#include "spi.h"
47#include "math.h"
48#include "main.h"
49#include "eeprom.h"
50#include <stdio.h>
51// --- EXTERNE VARIABLEN --------------------------------------------------------
52
53// --- LOKALE DEFINES - bitte hier dokumentieren --------------------------------
54
55/*************************************************************************************************************/
56
57/*************************************************************************************************************/
58#define VOLTAGE (0)
59#define CURRENT (1)
60#define TEMPERATURE (2)
61
62#define DEFAULT_ADS1260_TRANSMIT_TIMEOUT (10)
63#define DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT (10)
64#define ADS1260_SELF_OFFSET_CALIBRATION_TIMEOUT (2000) // > 16 * sampletime muss eingestellt werden
65#define ADS1260_SYSTEM_OFFSET_CALIBRATION_TIMEOUT (2000)
66#define ADS1260_GAIN_CALIBRATION_TIMEOUT (2000)
67
68#define COMMAND_POS (0)
69#define SEND_DATA_POS (1)
70#define RECEIVE_DATA_POS (2)
71
72#define SEND_DATA_NR_OF_BYTES (2)
73#define RECEIVE_DATA_NR_OF_BYTES (3)
74#define DATA_ARRAY_SIZE (3)
75
76#define REGISTER_READ_COMMAND (1 << 5)
77#define REGISTER_WRITE_COMMAND (1 << 6)
78
79#define SYSTEM_OFFSET_CALIBRATION_COMMAND (0x16)
80#define GAIN_CALIBRATION_COMMAND (0x17)
81#define SELF_OFFSET_CALIBRATION_COMMAND (0x19)
82 // Register Number:
83#define DATA_RATE_REGISTER (0x02)
84#define DATA_RATE_2_5 (0b00000 << 3)
85#define DATA_RATE_5 (0b00001 << 3)
86#define DATA_RATE_10 (0b00010 << 3)
87#define DATA_RATE_16_6 (0b00011 << 3)
88#define DATA_RATE_20 (0b00100 << 3)/*Default*/
89#define DATA_RATE_50 (0b00101 << 3)
90#define DATA_RATE_60 (0b00110 << 3)
91#define DATA_RATE_100 (0b00111 << 3)
92#define DATA_RATE_400 (0b01000 << 3)
93#define DATA_RATE_1200 (0b01001 << 3)
94#define DATA_RATE_2400 (0b01010 << 3)
95#define DATA_RATE_4800 (0b01011 << 3)
96#define DATA_RATE_7200 (0b01100 << 3)
97#define DATA_RATE_14400 (0b01101 << 3)
98#define DATA_RATE_19200 (0b01110 << 3)
99#define DATA_RATE_25600 (0b01111 << 3)
100#define DATA_RATE_40000 (0b10000 << 3)
101#define DATA_RATE_RESET_MASK ~(0b11111 << 3)
102
103#define DIGITAL_FILTER_REGISTER (DATA_RATE_REGISTER)
104#define FILTER_SINC1 (0b000 << 0)
105#define FILTER_SINC2 (0b001 << 0)
106#define FILTER_SINC3 (0b010 << 0)
107#define FILTER_SINC4 (0b011 << 0)
108#define FILTER_FIR (0b100 << 0)/*Default*/
109#define FILTER_RESET_MASK ~(0b111 << 0)
110
111
112#define CHOP_MODE_REGISTER (0x03)
113#define CHOP_MODE_NORMAL (0b00 << 5)/*Default*/
114#define CHOP_MODE_CHOP_MODE (0b01 << 5)
115#define CHOP_MODE_RESET_MASK ~(0b11 << 5)/*Default*/
116
117#define CONVERSION_MODE_REGISTER (CHOP_MODE_REGISTER)
118#define CONVERSION_MODE_CONTINIOUS (0 << 4)/*Default*/
119#define CONVERSION_MODE_PULSE (1 << 4)
120#define CONVERSION_MODE_RESET_MASK ~(1 << 4)
121
122#define CONVERSION_START_DELAY_REGISTER (CHOP_MODE_REGISTER)
123#define CONVERSION_START_DELAY_0u (0b0000 << 0)
124#define CONVERSION_START_DELAY_50u (0b0001 << 0)/*Default*/
125#define CONVERSION_START_DELAY_59u (0b0010 << 0)
126#define CONVERSION_START_DELAY_67u (0b0011 << 0)
127#define CONVERSION_START_DELAY_85u (0b0100 << 0)
128#define CONVERSION_START_DELAY_119u (0b0101 << 0)
129#define CONVERSION_START_DELAY_189u (0b0110 << 0)
130#define CONVERSION_START_DELAY_328u (0b0111 << 0)
131#define CONVERSION_START_DELAY_605u (0b1000 << 0)
132#define CONVERSION_START_DELAY_1_16m (0b1001 << 0)
133#define CONVERSION_START_DELAY_2_27m (0b1010 << 0)
134#define CONVERSION_START_DELAY_4_49m (0b1011 << 0)
135#define CONVERSION_START_DELAY_8_89m (0b1100 << 0)
136#define CONVERSION_START_DELAY_17_8m (0b1101 << 0)
137#define CONVERSION_START_RESET_MASK ~(0b1111 << 0)
138
139
140
141#define REFERENCE_CONFIG_REGISTER (0x06)
142#define INTERNAL_REFERENCE_ENABLE (1 << 4)
143#define INTERNAL_REFERENCE_DISABLE (0 << 4)/*Default*/
144#define INTERNAL_REFERENCE_RESET_MASK ~(1 << 4)
145
146#define SELECT_POS_REFERENCE_INTERNAL (0b00 << 2)
147#define SELECT_POS_REFERENCE_AVDD (0b01 << 2)/*Default*/
148#define SELECT_POS_REFERENCE_AIN0 (0b10 << 2)
149#define SELECT_POS_REFERENCE_AIN2 (0b11 << 2)
150
151#define SELECT_NEG_REFERENCE_INTERNAL (0b00 << 0)
152#define SELECT_NEG_REFERENCE_AVSS (0b01 << 0)/*Default*/
153#define SELECT_NEG_REFERENCE_AIN1 (0b10 << 0)
154#define SELECT_NEG_REFERENCE_AIN3 (0b11 << 0)
155
156#define SELECT_REFERENCE_RESET_MASK ~(0b1111 << 0)
157
158#define OFFSET_CAL_LOW_BYTE_REG (0x07)
159#define OFFSET_CAL_MID_BYTE_REG (0x08)
160#define OFFSET_CAL_HIGH_BYTE_REG (0x09)
161
162#define FSCALE_CAL_LOW_BYTE_REG (0x0A)
163#define FSCALE_CAL_MID_BYTE_REG (0x0B)
164#define FSCALE_CAL_HIGH_BYTE_REG (0x0C)
165
166#define INPUT_MUX_REGISTER (0x11)
167
168#define POS_INPUT_MUX_SELECT_AINCOM (0b0000 << 4)
169#define POS_INPUT_MUX_SELECT_AIN0 (0b0001 << 4)
170#define POS_INPUT_MUX_SELECT_AIN1 (0b0010 << 4)
171#define POS_INPUT_MUX_SELECT_AIN2 (0b0011 << 4)
172#define POS_INPUT_MUX_SELECT_AIN3 (0b0100 << 4)
173#define POS_INPUT_MUX_SELECT_AIN4 (0b0101 << 4)
174#define POS_INPUT_MUX_SELECT_INT_TEMP_SENSOR_POS (0b1011 << 4)
175#define POS_INPUT_MUX_SELECT_INT_AVDD_DIV4_POS (0b1100 << 4)
176#define POS_INPUT_MUX_SELECT_INT_DVDD_DIV4_POS (0b1101 << 4)
177#define POS_INPUT_MUX_SELECT_INPUTS_OPEN (0b1110 << 4)
178#define POS_INPUT_MUX_SELECT_VCOM (0b1111 << 4)
179
180#define NEG_INPUT_MUX_SELECT_AINCOM (0b0000 << 4)
181#define NEG_INPUT_MUX_SELECT_AIN0 (0b0001 << 0)
182#define NEG_INPUT_MUX_SELECT_AIN1 (0b0010 << 0)
183#define NEG_INPUT_MUX_SELECT_AIN2 (0b0011 << 0)
184#define NEG_INPUT_MUX_SELECT_AIN3 (0b0100 << 0)
185#define NEG_INPUT_MUX_SELECT_AIN4 (0b0101 << 0)
186#define NEG_INPUT_MUX_SELECT_INT_TEMP_SENSOR_NEG (0b1011 << 0)
187#define NEG_INPUT_MUX_SELECT_INT_AVDD_DIV4_NEG (0b1100 << 0)
188#define NEG_INPUT_MUX_SELECT_INT_DVDD_DIV4_NEG (0b1101 << 0)
189#define NEG_INPUT_MUX_SELECT_INPUTS_OPEN (0b1110 << 0)
190#define NEG_INPUT_MUX_SELECT_VCOM (0b1111 << 0)
191#define INPUT_MUX_SELECT_RESET_MASK ~(0b00000000 << 0)
192
193// --- LOKALE TYPE DEFS - bitte hier dokumentieren-------------------------------
194
195// --- DEFINITIONEN GLOBALER VARIABLEN - Bitte in Header dokumentieren ----------
196uint32_t ahCounter[50];
197int32_t nrOfValuesCurrent;
198int32_t avgValWithOffsetCompensation;
199int32_t avgValWithOffsetCommonModeOffsetCorrection;
200int32_t avgValWithOffsetCommonModeOffsetTemperatureCorrection;
201double current;
202double currentWithGainCorrection;
203double currentWithGainAndGainShuntTempCorrection;
204//double currentWithGainAndGainShuntTempAndGainChipTempCorrection;
205// --- LOKALE VARIABLEN - bitte hier dokumentieren ------------------------------
206static adc_state_enum_t ads1260DataCoversionState;
207
208static const uint8_t RREG_BaseOpcode = 0x20; // Read Register CMD
209static const uint8_t WREG_BaseOpcode = 0x40; // Write Register CMD
210static const uint8_t LOCK_Opcode = 0xF2; // Lock registers modification CMD
211static const uint8_t RDATA_Opcode = 0x12; // Read conversion DATA CMD
212
213static const uint8_t MODE3_regAdr = 0x05; // MODE3 register address
214static const uint8_t MODE3_STATENB = 6U; // Status enable bit position in MODE3 register
215static const uint8_t MODE3_CRCENB = 5U; // CRC enable bit position in MODE3 register
216
217static const uint8_t STATUS_regAdr = 0x01;
218static const uint8_t STATUS_LOCK = 7U;
219static const uint8_t STATUS_CRCERR = 6U;
220static const uint8_t STATUS_REFL_ALM = 3U;
221static const uint8_t STATUS_DRDY = 2U;
222
223
224static const uint8_t arbitraryByte = 0xEC; // Don't care byte
225static const uint8_t replyHeader = 0xFF;
226
227// --- LOKALE FUNKTIONS PROTOTYPEN ----------------------------------------------
228static void ADS_1260_SetConversionMode(SPI_HandleTypeDef * hspi, uint8_t conversionMode);
229static void ADS_1260_SetInternalReference(SPI_HandleTypeDef * hspi);
230static void ADS_1260_SetExternalReference(SPI_HandleTypeDef * hspi);
231static void ADS_1260_InputMuxSelect(SPI_HandleTypeDef * hspi, uint8_t muxSelect);
232static void ADS_1260_SetChopMode(SPI_HandleTypeDef * hspi, uint8_t chopMode);
233static void ADS_1260_ActivateStatusData(void);
234static void ADS_1260_ActivateLock(void);
235
236static uint32_t ADS1260_ProcessCurrent(int32_t current);
237volatile uint32_t newCurrentValue=0;
238//static uint32_t ADS1260_ProcessVoltage(int32_t voltage, sys_data_t * data);
239//static uint32_t ADS1260_ProcessTemperature(int32_t temperature, sys_data_t * data);
240
241// Funktionen werden extern
242
243// --- LOKALE FUNKTIONEN - bitte hier dokumentieren -----------------------------
244
245/*
246* @brief Einstellung Conversion Mode
247* @param kein
248* @retval kein
249*/
250static void ADS_1260_SetConversionMode(SPI_HandleTypeDef * hspi, uint8_t conversionMode)
251{
252 uint8_t spiData[DATA_ARRAY_SIZE];
253 // Read
254 spiData[COMMAND_POS] = (REGISTER_READ_COMMAND + CONVERSION_MODE_REGISTER);
255 // HAL_GPIO_WritePin(SPI3_NSS_GPIO_Port, SPI3_NSS_Pin, GPIO_PIN_RESET);
256 HAL_SPI_TransmitReceive(hspi, spiData, spiData, RECEIVE_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
257 // HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
258 // Modify
259 spiData[SEND_DATA_POS] = ((spiData[RECEIVE_DATA_POS] & CONVERSION_MODE_RESET_MASK) | conversionMode); // so gefriemelt dass der Conversionsmodus gesetzt wird und der Rest des Registers unberührt beleibt
260 // Write
261 spiData[COMMAND_POS] = (REGISTER_WRITE_COMMAND + CONVERSION_MODE_REGISTER);
262 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
263 HAL_SPI_TransmitReceive(hspi, spiData, spiData, SEND_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
264 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
265 // Read
266 spiData[COMMAND_POS] = (REGISTER_READ_COMMAND + CONVERSION_MODE_REGISTER);
267 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
268 HAL_SPI_TransmitReceive(hspi, spiData, spiData, RECEIVE_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
269 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
270 // Verify
271 if((spiData[RECEIVE_DATA_POS] & conversionMode) != conversionMode)
272 {
273 printf("ERROR ADS_1260_SetConversionMode\n");
274 while(1);
275 }
276
277}
278
279/*
280* @brief Einstellung Chop Mode
281* @param kein
282* @retval kein
283*/
284static void ADS_1260_SetChopMode(SPI_HandleTypeDef * hspi, uint8_t chopMode)
285{
286 uint8_t spiData[DATA_ARRAY_SIZE];
287 // Read
288 spiData[COMMAND_POS] = (REGISTER_READ_COMMAND + CHOP_MODE_REGISTER);
289 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
290 HAL_SPI_TransmitReceive(hspi, spiData, spiData, RECEIVE_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
291 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
292 // Modify
293 spiData[SEND_DATA_POS] = ((spiData[RECEIVE_DATA_POS] & CHOP_MODE_RESET_MASK) | chopMode); // so gefriemelt dass der Conversionsmodus gesetzt wird und der Rest des Registers unberührt beleibt
294 // Write
295 spiData[COMMAND_POS] = (REGISTER_WRITE_COMMAND + CHOP_MODE_REGISTER);
296 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
297 HAL_SPI_TransmitReceive(hspi, spiData, spiData, SEND_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
298 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
299 // Read
300 spiData[COMMAND_POS] = (REGISTER_READ_COMMAND + CHOP_MODE_REGISTER);
301 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
302 HAL_SPI_TransmitReceive(hspi, spiData, spiData, RECEIVE_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
303 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
304 // Verify
305 if((spiData[RECEIVE_DATA_POS] & chopMode) != chopMode)
306 {
307 printf("ERROR ADS_1260_SetChopMode\n");
308 while(1);
309 }
310}
311
312/*
313* @brief Einstellung Datarate
314* @param kein
315* @retval kein
316*/
317void ADS_1260_SetDataRate(SPI_HandleTypeDef * hspi, uint8_t dataRate)
318{
319 uint8_t spiData[DATA_ARRAY_SIZE];
320 // Read
321 spiData[COMMAND_POS] = (REGISTER_READ_COMMAND + DATA_RATE_REGISTER);
322 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
323 HAL_SPI_TransmitReceive(hspi, spiData, spiData, RECEIVE_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
324 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
325 // Modify
326 spiData[SEND_DATA_POS] = ((spiData[RECEIVE_DATA_POS] & DATA_RATE_RESET_MASK) | dataRate); // so gefriemelt dass die Datarate gesetzt wird und der Rest des Registers unberührt beleibt
327 // Write
328 spiData[COMMAND_POS] = (REGISTER_WRITE_COMMAND + DATA_RATE_REGISTER);
329 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
330 HAL_SPI_TransmitReceive(hspi, spiData, spiData, SEND_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
331 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
332 // Read
333 spiData[COMMAND_POS] = (REGISTER_READ_COMMAND + DATA_RATE_REGISTER);
334 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
335 HAL_SPI_TransmitReceive(hspi, spiData, spiData, RECEIVE_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
336 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
337 // Verify
338 if((spiData[RECEIVE_DATA_POS] & dataRate) != dataRate)
339 {
340 printf("ERROR ADS_1260_SetDataRate\n");
341 while(1);
342 }
343
344}
345
346/*
347* @brief Einstellung Filtertyp
348* @param kein
349* @retval kein
350*/
351void ADS_1260_SetDigitalFilter(SPI_HandleTypeDef * hspi, uint8_t digitalFilter)
352{
353 uint8_t spiData[DATA_ARRAY_SIZE];
354 // Read
355 spiData[COMMAND_POS] = (REGISTER_READ_COMMAND + DIGITAL_FILTER_REGISTER);
356 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
357 HAL_SPI_TransmitReceive(hspi, spiData, spiData, RECEIVE_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
358 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
359 // Modify
360 spiData[SEND_DATA_POS] = ((spiData[RECEIVE_DATA_POS] & FILTER_RESET_MASK) | digitalFilter); // so gefriemelt dass der Filter gesetzt wird und der Rest des Registers unberührt beleibt
361 // Write
362 spiData[COMMAND_POS] = (REGISTER_WRITE_COMMAND + DIGITAL_FILTER_REGISTER);
363 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
364 HAL_SPI_TransmitReceive(hspi, spiData, spiData, SEND_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
365 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
366 // Read
367 spiData[COMMAND_POS] = (REGISTER_READ_COMMAND + DIGITAL_FILTER_REGISTER);
368 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
369 HAL_SPI_TransmitReceive(hspi, spiData, spiData, RECEIVE_DATA_NR_OF_BYTES, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
370 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
371 // Verify
372 if((spiData[RECEIVE_DATA_POS] & digitalFilter) != digitalFilter)
373 {
374 printf("ERROR ADS_1260_SetDigitalFilter\n");
375 while(1);
376 }
377}
378
379/*
380* @brief schaltet über die Mux die Eingänge auf den ADC
381* @param kein
382* @retval kein
383*/
384static void ADS_1260_InputMuxSelect(SPI_HandleTypeDef * hspi, uint8_t muxSelect)
385{
386 // Write
387 uint8_t spiData[3] = {(REGISTER_WRITE_COMMAND + INPUT_MUX_REGISTER), muxSelect, 0};
388 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
389 HAL_SPI_TransmitReceive(hspi, spiData, spiData, 2, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
390 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
391 // Read
392 spiData[COMMAND_POS] = (REGISTER_READ_COMMAND + INPUT_MUX_REGISTER);
393 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
394 HAL_SPI_TransmitReceive(hspi, spiData, spiData, 3, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
395 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
396 // Verifie
397 if(spiData[RECEIVE_DATA_POS] != muxSelect)
398 {
399 printf("ERROR ADS_1260_InputMuxSelect\n");
400// while(1);
401 }
402}
403
404
405/*
406* @brief schaltet die interne 2.500 Volt Referenzspannungsquelle ein
407* und wählt diese als Referenspannungsquelle aus
408* @param kein
409* @retval kein
410*/
411static void ADS_1260_SetInternalReference(SPI_HandleTypeDef * hspi)
412{
413 // Write
414 uint8_t spiData[3] = {(REGISTER_WRITE_COMMAND + REFERENCE_CONFIG_REGISTER), (INTERNAL_REFERENCE_ENABLE + SELECT_POS_REFERENCE_INTERNAL + SELECT_NEG_REFERENCE_INTERNAL), 0};
415 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
416 HAL_SPI_TransmitReceive(hspi, spiData, spiData, 2, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
417 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
418 // Read
419 spiData[COMMAND_POS] = (REGISTER_READ_COMMAND + REFERENCE_CONFIG_REGISTER);
420 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
421 HAL_SPI_TransmitReceive(hspi, spiData, spiData, 3, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
422 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
423 // Verifie
424 if(spiData[RECEIVE_DATA_POS] != (INTERNAL_REFERENCE_ENABLE + SELECT_POS_REFERENCE_INTERNAL + SELECT_NEG_REFERENCE_INTERNAL))
425 {
426 printf("ERROR ADS_1260_SetInternalReference\n");
427 while(1);
428 }
429
430}
431
432
433/*
434* @brief schaltet die interne 2.500 Volt Referenzspannungsquelle ein
435* und wählt diese als Referenspannungsquelle aus
436* @param kein
437* @retval kein
438*/
439static void ADS_1260_SetExternalReference(SPI_HandleTypeDef * hspi)
440{
441 // Write
442 uint8_t spiData[3] = {(REGISTER_WRITE_COMMAND + REFERENCE_CONFIG_REGISTER), (INTERNAL_REFERENCE_DISABLE + SELECT_POS_REFERENCE_AIN0 + SELECT_NEG_REFERENCE_AIN1), 0};
443 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
444 HAL_SPI_TransmitReceive(hspi, spiData, spiData, 2, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
445 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
446 // Read
447 spiData[COMMAND_POS] = (REGISTER_READ_COMMAND + REFERENCE_CONFIG_REGISTER);
448 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
449 HAL_SPI_TransmitReceive(hspi, spiData, spiData, 3, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
450 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
451 // Verifie
452 if(spiData[RECEIVE_DATA_POS] != (INTERNAL_REFERENCE_DISABLE + SELECT_POS_REFERENCE_AIN0 + SELECT_NEG_REFERENCE_AIN1))
453 {
454 printf("ERROR ADS_1260_SetInternalReference\n");
455 while(1);
456 }
457
458}
459
460
461
462
463
464/************************************************** KAL *****************************************************************/
465/*
466* @brief Software Offsetkalibrierung für die Strommessung.
467* Voraussetzungen: Es darf kein Strom über den Shunt fließen.
468* Warten bis Mittelwertbildung abgeschlossen ist.
469* @param kein
470* @retval kein
471*/
472void ADS_1260_BatteryCurrentOffsetCalibrationStart(sys_data_t * data)
473{
474 data->s.parameter.batteryCurrentOffset = data->s.values.battryCurrentRaw;
475 data->s.parameter.batteryCurrentOffsetRefTemperatureShunt = data->s.values.shuntTemperature;
476 data->s.parameter.batteryCurrentOffsetRefTemperatureChip = data->s.values.chipTemperature;
477 data->s.parameter.batteryCurrentOffsetRefshuntVoltage = data->s.values.shuntVoltage;
478 EEPROM_storeConfig(&sys_data,0);
479}
480
481void ADS_1260_BatteryCurrentOffsetCommonModeErrorComepensationStart(sys_data_t * data)
482{
483 //speichere geänderte CommonMode Spannung
484 data->s.parameter.batteryCurrentOffsetCommonModeCalibrationVoltage = data->s.values.shuntVoltage;
485
486 //Delta berechnen
487 //Kompensationswert speichern in ADC Steps *1000 pro mV Common Mode Voltage
488 int32_t deltaU = data->s.parameter.batteryCurrentOffsetCommonModeCalibrationVoltage - data->s.parameter.batteryCurrentOffsetRefshuntVoltage;
489
490 //Entstandene Abweichung durch Common Mode Fehler, ist aktueller Messwert mit vorherigen Kompensationen
491 int32_t deltaADC = avgValWithOffsetCompensation;
492 int32_t compensationFactor = deltaADC * 1000 / deltaU;
493 data->s.parameter.batteryCurrentOffsetCommonModeCompensationFactor = compensationFactor;
494 EEPROM_storeConfig(&sys_data,0);
495}
496
497void ADS_1260_BatteryCurrentOffsetTemperatureErrorComepensationStart(void)
498{
499 //speichere geänderte Temperatur
500 //Achtung die Offset Kompeensation machen wir hier absichtlich mit der Chip Temperatur und nicht mit der Shunt Temperatur
501 //Die Chip spiegeelt genaueer die Temperatur der ADC und Strommessverstärker wieder. Der Offset driftt hängt von der Temp der ADC/VREF/Messverstrker zusammen
502 //und nicht mit der Temp der Shunt Widerstände
503 sys_data.s.parameter.batteryCurrentOffsetTemperatureCalibrationTemperature = sys_data.s.values.chipTemperature;
504
505
506 //Delta berechnen
507 int32_t deltaT = sys_data.s.parameter.batteryCurrentOffsetTemperatureCalibrationTemperature - sys_data.s.parameter.batteryCurrentOffsetRefTemperatureChip;
508 int32_t deltaADC = avgValWithOffsetCommonModeOffsetCorrection;
509 int32_t compensationFactor = deltaADC * 1000 / deltaT;
510 sys_data.s.parameter.batteryCurrentOffsetTemperatureCompensationFactor = compensationFactor;
511 EEPROM_storeConfig(&sys_data,0);
512}
513
514
515
516
517void ADS_1260_BatteryCurrentGainCalibrationStart(sys_data_t * data)
518{
519 double helper;
520 printf("--- Gain CAL ---");
521 if(data->s.parameter.batteryCurrentGainRefCurrent == 0) // Fehler
522 {
523 printf("ADS_1260_BatteryCurrentGainCalibrationStart: ERROR IN CALIBRATION, NO REFERENCE CURRENT!\n");
524 return;
525 }
526
527
528
529 // Sollstrom durch Batteriestrom teilen
530 // Sollstrom ist in mA also umrechen in A, da Batteriestrom ("current") auch in A
531 // ACHTUNG Das Punkt 0 ist wichtig, muss mit Fließkomma Berechnung durchgeführt werden!!!!
532 helper = (data->s.parameter.batteryCurrentGainRefCurrent / 1000.0 ) / current;
533 // in den Batteriegain umrechnen
534 data->s.parameter.batteryCurrentGainCorrectionFaktor = (helper * 1000000.0);
535 // schreibe Temperatur bei der kalibriert wurde
536 data->s.parameter.batteryCurrentGainRefTempShunt = data->s.values.shuntTemperature;
537 data->s.parameter.batteryCurrentGainRefTempChip = data->s.values.chipTemperature;
538
539 printf("I (without compensation)=%f\n", current);
540 printf("I Referenz=%f\n", data->s.parameter.batteryCurrentGainRefCurrent / 1000.0);
541 printf("Tshunt=%f\n", data->s.parameter.batteryCurrentGainRefTempShunt/100.0);
542 printf("Tship=%f\n", data->s.parameter.batteryCurrentGainRefTempChip/100.0);
543 printf("Korrekturfaktor=%f\n", data->s.parameter.batteryCurrentGainCorrectionFaktor*1000000.0 );
544 printf("--- Gain CAL ENDE---");
545 EEPROM_storeConfig(&sys_data,0);
546}
547//Self Heat Kompensation
548void ADS_1260_BatteryCurrentGainTemperatureCalibrationShuntStart(void)
549{
550 double helper;
551 printf("--- Gain Drift CAL ---");
552 //speichere aktuelle Temperatur
553 sys_data.s.parameter.batteryCurrentGainTemperatureCalibrationShuntTemperature = sys_data.s.values.shuntTemperature;
554 printf("Actual T=%f C\n", sys_data.s.parameter.batteryCurrentGainTemperatureCalibrationShuntTemperature/100.0);
555 //Temperaturänderung berechnen
556 int32_t deltaTShunt = ( sys_data.s.values.shuntTemperature - sys_data.s.parameter.batteryCurrentGainRefTempShunt);
557 printf("delta T=%f C\n", deltaTShunt/100.0);
558
559 helper = currentWithGainCorrection;
560 printf("Acutal I=%f A(without gain temp drift correction)\n", currentWithGainCorrection);
561 printf("Ref I=%f\n", sys_data.s.parameter.batteryCurrentGainRefCurrent/1000.0);
562 // Sollstrom durch Batteriestrom teilen
563 // wir erhalten den Korrektur Faktor für die aktuelle Temperatur
564 helper = (sys_data.s.parameter.batteryCurrentGainRefCurrent/1000.0) / helper;
565
566 // Speichere Korrekturfaktor pro Schritt Temperaturänderung
567 helper = helper - 1.0;
568
569 helper = helper / (deltaTShunt);
570
571 //Speicher um Faktor 10000000 erhöht um Kommazahlen zu vermeiden
572 sys_data.s.parameter.batteryCurrentGainTemperatureCompensationShuntFactor = helper*1000000000.0;
573
574 printf("Korrekturfaktor=%f [ 1 / Celsius]\n", (sys_data.s.parameter.batteryCurrentGainTemperatureCompensationShuntFactor / 1000000000.0 * 100) + 1.0 );
575 printf("--- Gain Drift CAL ENDE ---");
576 EEPROM_storeConfig(&sys_data,0);
577}
578
579////Ambient Temperature
580//void ADS_1260_BatteryCurrentGainTemperatureCalibrationChipStart()
581//{
582// double helper;
583// //speichere geänderte Temperatur
584// sys_data.s.parameter.batteryCurrentGainTemperatureCalibrationChipTemperature = sys_data.s.values.chipTemperature;
585// int32_t deltaT = sys_data.s.values.chipTemperature - sys_data.s.parameter.batteryCurrentGainRefTempChip;
586//
587//
588// helper = currentWithGainAndGainShuntTempCorrection;
589// // Sollstrom durch Batteriestrom teilen
590// // wir erhalten den Korrektur Faktor für die aktuelle Temperatur
591// helper = (sys_data.s.parameter.batteryCurrentGainRefCurrent/1000.0) / helper;
592//
593// // Speichere Korrekturfaktor pro Schritt Temperaturänderung
594// helper = helper - 1.0;
595//
596// helper = helper / deltaT;
597//
598// //Speicher um Faktor 10000000 erhöht um Kommazahlen zu vermeiden
599// sys_data.s.parameter.batteryCurrentGainTemperatureCompensationChipFactor = helper*1000000000.0;
600//
601//}
602
603
604/*
605* @brief Rohwerte ADC in Strom umrechnen
606* @param kein
607* @retval kein
608*/
609
610#define BATTERY_CURRENT_FILTER 2
611
612static uint32_t ADS1260_ProcessCurrent(int32_t newval)
613{
614 static signed long avgsum = 0;
615 static int meas_counter;
616 if (meas_counter < INT32_MAX) meas_counter++;
617 int32_t avgval;
618
619 // Filterlängen in 2er-Potenzen --> Compiler optimiert
620 avgsum -= avgsum/ BATTERY_CURRENT_FILTER;
621 avgsum += newval;
622 avgval = avgsum / BATTERY_CURRENT_FILTER;
623 sys_data.s.values.battryCurrentRaw = avgval;
624 /**********************Offset Kompensation:*******************************/
625 // Offset abziehen
626 avgValWithOffsetCompensation = avgval - sys_data.s.parameter.batteryCurrentOffset;
627 // Temperaturabhängiges Offset abziehen
628 // in ADC Messwerten mal Abweichung von Referenttemperatur
629 //current = current - ((sys_data.s.ads1260.s.offsetTemperatureFactorCurrent / 1000.0) * ((sys_data.s.device.parameter.shuntTemperature - sys_data.s.ads1260.s.refTempSoftwareOffsetCalibrationCurrent)/1000.0));
630 /**********************Offset Kompensation:*******************************/
631
632
633 /********************** START Common Mode Kompensation:*******************************/
634 //Berechne Änderung der aktuellen Spannung am Shunt zu der Spannung am shunt bei Kalibrierung
635 int32_t commonModeDeltaU = ((int32_t)sys_data.s.values.shuntVoltage - (int32_t)sys_data.s.parameter.batteryCurrentOffsetRefshuntVoltage) ;
636 int32_t commonModeErrorAdcSteps = (commonModeDeltaU * sys_data.s.parameter.batteryCurrentOffsetCommonModeCompensationFactor) / 1000.0 ;
637 sys_data.s.values.batteryCurrentOffsetCommonModeCorrectionADCSteps = commonModeErrorAdcSteps;
638 avgValWithOffsetCommonModeOffsetCorrection = avgValWithOffsetCompensation - commonModeErrorAdcSteps;
639 /********************** ENDE Common Mode Kompensation:*******************************/
640
641 /********************** START Offset Temperature Kompensation*******************************/
642 //Berechne Änderung der aktuellen Spannung am Shunt zu der Spannung am shunt bei Kalibrierung
643 //Achtung wir arbeiten für die Offset Temperatur Kompenssation mit der Chip Temperatur, nicht mit der Shunt Temperatur, vgl Kal. Faunktion
644 double temperatureDeltaT = ((int32_t)sys_data.s.values.chipTemperature - (int32_t) sys_data.s.parameter.batteryCurrentOffsetRefTemperatureChip);
645 int32_t temperatureErrorAdcSteps = (temperatureDeltaT * sys_data.s.parameter.batteryCurrentOffsetTemperatureCompensationFactor) / 1000.0 ;
646 avgValWithOffsetCommonModeOffsetTemperatureCorrection = avgValWithOffsetCommonModeOffsetCorrection - temperatureErrorAdcSteps;
647 /********************** ENDE Offset Temperature Kompensation *******************************/
648
649
650
651
652 // ADC Messwerte nach Mittwelwertbildung und Offset speichern
653 //sys_data.s.ads1260.s.mwADCStepsWithOffsetCorrectionCurrent = current;
654
655 // 250 resultiert aus 100µOhm Shunt + (Verstärkung Strommessverstärker = 20) * 2 -> Umrechnung in Strom
656 // 200 resultiert aus 125µOhm Shunt + (Verstärkung Strommessverstärker = 20) * 2 -> Umrechnung in Strom
657 // 2.5 = Vref, externe Referenz ist 3.0V
658 // 0x800000 = ADC Auflösung
659 #if (DEVICETYPE == 500)
660 current = ((avgValWithOffsetCommonModeOffsetTemperatureCorrection * (double)3.0 * 200.0) / (double)0x800000);
661 #elif (DEVICETYPE == 250)
662 current = ((avgValWithOffsetCommonModeOffsetTemperatureCorrection * (double)3.0 * 100.0) / (double)0x800000);
663 #elif (DEVICETYPE == 125)
664 current = ((avgValWithOffsetCommonModeOffsetTemperatureCorrection * (double)3.0 * 50.0) / (double)0x800000);
665 #else
666 #error No valid device type
667 #endif
668 // Gain aus Sysdata
669 currentWithGainCorrection = current * (sys_data.s.parameter.batteryCurrentGainCorrectionFaktor / 1000000.0);
670
671 /**********************Gain Temperatur Kompensation:*******************************/
672 // Wenn sich in Abhängigkeit von der Temperatur das Gain ändert wird der Messwert mit einem Wert 1 +/- einem kleinen Faktor
673 // der abhängig von der Temperaturabweichung ist multipliziert
674 //ausgabe = ausgabe * ( 1 + ((sys_data.s.ads1260.s.gainTemperatureFactorCurrent * ((sys_data.s.device.parameter.shuntTemperature - sys_data.s.ads1260.s.refTempSoftwareGainCalibrationCurrent) / 1000.0) / 1000000000.0)));
675 /**********************Gain Temperatur Kompensation:*******************************/
676
677 #ifdef PRINT_BATTERY_CURRENT
678 // Ausgabe runden auf %f.3
679 printf("battery current = %.4fA\n", current);
680 #endif
681
682
683
684
685 double temperatureDeltaTShunt;
686 //double temperatureDeltaTChip;
687 temperatureDeltaTShunt = ((int32_t)sys_data.s.values.shuntTemperature - (int32_t) sys_data.s.parameter.batteryCurrentGainRefTempShunt);
688 //temperatureDeltaTChip = ((int32_t)sys_data.s.values.chipTemperature - (int32_t) sys_data.s.parameter.batteryCurrentGainRefTempChip);
689
690 // Gain Temperaturkompensation anwenden - Shunt
691 double f = (sys_data.s.parameter.batteryCurrentGainTemperatureCompensationShuntFactor / 1000000000.0);
692 double k = 1.0 + (temperatureDeltaTShunt * f);
693 currentWithGainAndGainShuntTempCorrection = currentWithGainCorrection * k;
694
695
696 // Gain Temperaturkompensation anwenden - Ambient
697 //double f2 = (sys_data.s.parameter.batteryCurrentGainTemperatureCompensationChipFactor / 1000000000.0);
698 //double k2 = 1.0 + ( temperatureDeltaTChip * f2);
699 //k2=1; //Testabschaltung
700 //currentWithGainAndGainShuntTempAndGainChipTempCorrection = currentWithGainAndGainShuntTempCorrection * k2;
701
702
703
704 // printf("i=%f A. ist=%f, fs=%f, dTs=%f\n", currentWithGainCorrection, currentWithGainAndGainShuntTempCorrection, k, temperatureDeltaTShunt );
705
706 //Endergebniss in mA speichern
707 #if (DEVICETYPE == 500)
708 if ((currentWithGainAndGainShuntTempCorrection > 550.0) || (currentWithGainAndGainShuntTempCorrection < -550.0))
709 {
710 sys_data.s.values.batteryCurrent = sys_data.s.values.fast_current;
711 }
712 else
713 {
714 sys_data.s.values.batteryCurrent = currentWithGainAndGainShuntTempCorrection * 1000.0;
715 }
716 #elif (DEVICETYPE == 250)
717 if ((currentWithGainAndGainShuntTempCorrection > 275.0) || (currentWithGainAndGainShuntTempCorrection < -275.0))
718 {
719 sys_data.s.values.batteryCurrent = sys_data.s.values.fast_current;
720 }
721 else
722 {
723 sys_data.s.values.batteryCurrent = currentWithGainAndGainShuntTempCorrection * 1000.0;
724 }
725 #elif (DEVICETYPE == 125)
726 if ((currentWithGainAndGainShuntTempCorrection > 137.0) || (currentWithGainAndGainShuntTempCorrection < -137.0))
727 {
728 sys_data.s.values.batteryCurrent = sys_data.s.values.fast_current;
729 }
730 else
731 {
732 sys_data.s.values.batteryCurrent = currentWithGainAndGainShuntTempCorrection * 1000.0;
733 }
734 #else
735 #error No valid device type
736 #endif
737
738
739
740 if (meas_counter > (BATTERY_CURRENT_FILTER *10)) // Nur aktualiseren, wenn es schon ausreichend Messwerte gab
741 {
742 // höchster und niedrigster Stromwert werden gespeichert
743 if(sys_data.s.values.batteryCurrent > sys_data.s.values.batteryCurrentMax)
744 {
745 sys_data.s.values.batteryCurrentMax = sys_data.s.values.batteryCurrent;
746 }
747 if(sys_data.s.values.batteryCurrent < sys_data.s.values.batteryCurrentMin)
748 {
749 sys_data.s.values.batteryCurrentMin = sys_data.s.values.batteryCurrent;
750 }
751 }
752
753 newCurrentValue=1;
754
755 return 0;
756}
757
758
759// --- GLOBALE FUNKTIONEN - bitte in Header dokumentieren------------------------
760
761void ADS1260_init(void)
762{
763 uint8_t sdata[10] = {0x47,0x00,0x00,0x00,0x00,0x00};
764 /* 0*/ ads1260DataCoversionState = ADC_STATE_INITIALIZE;
765 /* 3*/ HAL_GPIO_WritePin(ADC_START_CONV_GPIO_Port, ADC_START_CONV_Pin, GPIO_PIN_SET);
766 HAL_Delay(150); // Delay weil die Vref braucht zeit um sich zu stabilisieren (siehe Datenblatt Seite 9)
767 /* 1*/ //HAL_GPIO_WritePin(ADC_POWER_DOWN_GPIO_Port, ADC_POWER_DOWN_Pin, GPIO_PIN_RESET);
768 //HAL_Delay(150); // Delay weil die Vref braucht zeit um sich zu stabilisieren (siehe Datenblatt Seite 9)
769 /* 1*/ //HAL_GPIO_WritePin(ADC_POWER_DOWN_GPIO_Port, ADC_POWER_DOWN_Pin, GPIO_PIN_SET);
770 //HAL_Delay(150); // Delay weil die Vref braucht zeit um sich zu stabilisieren (siehe Datenblatt Seite 9)
771 /* 2*/ HAL_GPIO_WritePin(ADC_RESET_GPIO_Port, ADC_RESET_Pin, GPIO_PIN_RESET);
772 HAL_Delay(150); // Delay weil die Vref braucht zeit um sich zu stabilisieren (siehe Datenblatt Seite 9)
773 /* 2*/ HAL_GPIO_WritePin(ADC_RESET_GPIO_Port, ADC_RESET_Pin, GPIO_PIN_SET);
774 HAL_Delay(150); // Delay weil die Vref braucht zeit um sich zu stabilisieren (siehe Datenblatt Seite 9)
775 /* 3*/ HAL_GPIO_WritePin(ADC_START_CONV_GPIO_Port, ADC_START_CONV_Pin, GPIO_PIN_RESET);
776
777 /* 4*/ //while(HAL_GPIO_ReadPin(ADC_DATA_READY_GPIO_Port, ADC_DATA_READY_Pin) == GPIO_PIN_RESET);
778 HAL_NVIC_SetPriority(EXTI2_IRQn, 2, 0);
779 HAL_NVIC_EnableIRQ(EXTI2_IRQn);
780
781 /* 5*/ ADS_1260_SetExternalReference(&hspi3);
782 HAL_Delay(150);
783 /* 6*/ ADS_1260_SetDataRate(&hspi3, DATA_RATE_20);
784 // /* 7*/ ADS_1260_SetDigitalFilter(&hspi1, FILTER_SINC4);
785 /* 8*/ ADS_1260_SetConversionMode(&hspi3, CONVERSION_MODE_CONTINIOUS);
786 // langsamer
787 ADS_1260_SetChopMode(&hspi3, CHOP_MODE_CHOP_MODE);
788 ADS_1260_InputMuxSelect(&hspi3, POS_INPUT_MUX_SELECT_AIN2 + NEG_INPUT_MUX_SELECT_AIN3);
789
790 ADS_1260_ActivateStatusData();
791 ADS_1260_ActivateLock();
792
793 /*10*/ //ADS_1260_SelfOffsetCalibration(&hspi1);
794 HAL_Delay(150);
795 /*x*/ ads1260DataCoversionState = ADC_STATE_READY_FOR_CONVERSION;
796 ADS1260_StartConversion();
797}
798
799
800void ADS1260_StartConversion(void)
801{
802 HAL_GPIO_WritePin(ADC_START_CONV_GPIO_Port, ADC_START_CONV_Pin, GPIO_PIN_SET);
803}
804
805void ADS1260_ReadConversion(void)
806{
807 extern CRC_HandleTypeDef hcrc;
808 convert_union_t convert;
809
810 // CRC2
811 uint8_t spiDataIn[9] = { RDATA_Opcode, arbitraryByte, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
812 spiDataIn[2] = HAL_CRC_Calculate(&hcrc, (uint32_t*) spiDataIn, 2);
813 uint8_t spiDataOut[9] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
814
815 int32_t value = 0;
816 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
817 HAL_SPI_TransmitReceive(&hspi3, spiDataIn, spiDataOut, 9, DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
818 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
819
820 if (spiDataOut[0] == replyHeader && spiDataOut[1] == spiDataIn[0] && spiDataOut[2] == spiDataIn[1] && spiDataOut[3] == spiDataIn[2] && spiDataOut[8] == HAL_CRC_Calculate(&hcrc, (uint32_t*) &spiDataOut[4], 4))
821 {
822 uint8_t STATUS_reg = spiDataOut[4];
823
824 if ((STATUS_reg & (1 << STATUS_LOCK)) && (STATUS_reg & (1 << STATUS_DRDY)) && !(STATUS_reg & (1 << STATUS_CRCERR)) && !(STATUS_reg & (1 << STATUS_REFL_ALM)))
825 {
826 // Rohwerte Byteswitch
827 convert.s[3] = 0;
828 convert.s[2] = spiDataOut[5];
829 convert.s[1] = spiDataOut[6];
830 convert.s[0] = spiDataOut[7];
831
832 // Vorzeichen ausrechnen (24 bit MSB = Vorzeichenbit muss auf 32 bit umgesetzt werden)
833 if(convert.w >= 0x800000)
834 {
835 convert.sw = -(0xFFFFFF - convert.w);
836 value = convert.sw;
837 }
838 else if(convert.w < 0x800000)
839 {
840 //convert.sw = convert.w;
841 value = convert.w;
842 }
843 }
844 else
845 {
846 sys_data.s.values.adc_restarts++;
847 ADS1260_init();
848 }
849
850 }
851 else
852 {
853 sys_data.s.values.adc_restarts++;
854 ADS1260_init();
855 }
856
857 ADS1260_ProcessCurrent(value);
858}
859
860//-----------------------------------------------------------------------------
861
862static void ADS_1260_ActivateLock(void)
863{
864 extern CRC_HandleTypeDef hcrc;
865 const int maxReTries = 5;
866 int lockIsWritten = 0;
867
868 for (int i = 0; i < maxReTries; i++)
869 {
870 // Sendin LOCK command CRC2
871 uint8_t Din[] = { LOCK_Opcode, arbitraryByte, 0x00, 0x00 };
872 Din[2] = HAL_CRC_Calculate(&hcrc, (uint32_t*) Din, 2);
873 uint8_t Dout[] = { 0x00, 0x00, 0x00, 0x00 };
874
875 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
876 HAL_SPI_TransmitReceive(&hspi3, Din, Dout, sizeof(Din) / sizeof(Din[0]), DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
877 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
878
879 if (Dout[0] == replyHeader && Dout[1] == Din[0] && Dout[2] == Din[1] && Dout[3] == Din[2])
880 {
881 lockIsWritten = 1;
882 break;
883 }
884 else continue;
885 }
886
887 if (!lockIsWritten)
888 while (1)
889 { // Blink the RED LED forever
890 HAL_GPIO_TogglePin(LED_ERROR_GPIO_Port, LED_ERROR_Pin);
891 HAL_Delay(350);
892 }
893
894 int lockIsWrittenCorrect = 0;
895 // Reading STATUS register to make sure that LOCK is active
896 for (int i = 0; i < maxReTries; i++)
897 {
898 // Reading the content of the STATUS register CRC2
899 uint8_t Din[] = { RREG_BaseOpcode | STATUS_regAdr, arbitraryByte, 0x00, 0x00, 0x00, 0x00 };
900 Din[2] = HAL_CRC_Calculate(&hcrc, (uint32_t*) Din, 2);
901 uint8_t Dout[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
902
903 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
904 HAL_SPI_TransmitReceive(&hspi3, Din, Dout, sizeof(Din) / sizeof(Din[0]), DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
905 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
906
907 if (Dout[0] == replyHeader && Dout[1] == Din[0] && Dout[2] == Din[1] && Dout[3] == Din[2] && Dout[5] == HAL_CRC_Calculate(&hcrc, (uint32_t*)&Dout[4], 1))
908 {
909 uint8_t STATUS_reg = Dout[4];
910 if (STATUS_reg & (1U << STATUS_LOCK))
911 {
912 lockIsWrittenCorrect = 1;
913 break;
914 }
915 }
916 else continue;
917 }
918
919 if (!lockIsWrittenCorrect)
920 while (1)
921 { // Blink the RED LED forever
922 HAL_GPIO_TogglePin(LED_ERROR_GPIO_Port, LED_ERROR_Pin);
923 HAL_Delay(400);
924 }
925
926}
927
928//-----------------------------------------------------------------------------
929
930static void ADS_1260_ActivateStatusData(void)
931{
932 extern CRC_HandleTypeDef hcrc;
933 const int maxReTries = 5;
934 int mode3IsRead = 0;
935 uint8_t MODE3_Reg;
936
937 for (int i = 0; i < maxReTries; i++)
938 {
939 // Reading the content of the MODE3 register
940 uint8_t Din[] = { RREG_BaseOpcode | MODE3_regAdr, arbitraryByte, 0x00 };
941 uint8_t Dout[] = { 0x00, 0x00, 0x00 };
942
943 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
944 HAL_SPI_TransmitReceive(&hspi3, Din, Dout, sizeof(Din) / sizeof(Din[0]), DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
945 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
946
947 if (Dout[0] == replyHeader && Dout[1] == Din[0])
948 {
949 MODE3_Reg = Dout[2]; // Saving the content of the MODE3 register
950 mode3IsRead = 1;
951 break;
952 }
953 else continue;
954 }
955
956 if (!mode3IsRead)
957 while (1)
958 { // Blink the RED LED forever
959 HAL_GPIO_TogglePin(LED_ERROR_GPIO_Port, LED_ERROR_Pin);
960 HAL_Delay(200);
961 }
962
963 // Setting STATENB and CRCENB bits in MODE3 register
964 MODE3_Reg |= (1U << MODE3_STATENB) | (1U << MODE3_CRCENB);
965
966 int mode3IsWritten = 0;
967
968 for (int i = 0; i < maxReTries; i++)
969 {
970 // Writing back the content of the MODE3 register
971 uint8_t Din[] = { WREG_BaseOpcode | MODE3_regAdr, MODE3_Reg };
972 uint8_t Dout[] = { 0x00, 0x00 };
973
974 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
975 HAL_SPI_TransmitReceive(&hspi3, Din, Dout, sizeof(Din) / sizeof(Din[0]), DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
976 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
977
978 if (Dout[0] == replyHeader && Dout[1] == Din[0])
979 {
980 mode3IsWritten = 1;
981 break;
982 }
983 else continue;
984 }
985
986 if (!mode3IsWritten)
987 while (1)
988 { // Blink the RED LED forever
989 HAL_GPIO_TogglePin(LED_ERROR_GPIO_Port, LED_ERROR_Pin);
990 HAL_Delay(250);
991 }
992
993 int mode3IsWrittenCorrect = 0;
994
995 // We have activated CRC in every data packet, so we need take it into account
996 for (int i = 0; i < maxReTries; i++)
997 {
998 // Reading one more time the content of the MODE3 register CRC2
999 uint8_t Din[] = { RREG_BaseOpcode | MODE3_regAdr, arbitraryByte, 0x00, 0x00, 0x00, 0x00 };
1000 Din[2] = HAL_CRC_Calculate(&hcrc, (uint32_t*) Din, 2);
1001 uint8_t Dout[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
1002
1003 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_RESET);
1004 HAL_SPI_TransmitReceive(&hspi3, Din, Dout, sizeof(Din) / sizeof(Din[0]), DEFAULT_ADS1260_TRANSMIT_RECEIVE_TIMEOUT);
1005 //HAL_GPIO_WritePin(ADC_SPI1_NSS_GPIO_Port, ADC_SPI1_NSS_Pin, GPIO_PIN_SET);
1006
1007 if (Dout[0] == replyHeader && Dout[1] == Din[0] && Dout[2] == Din[1] && Dout[3] == Din[2] && Dout[5] == HAL_CRC_Calculate(&hcrc, (uint32_t*)&Dout[4], 1))
1008 {
1009 if ((Dout[4] & (1U << MODE3_STATENB)) && (Dout[4] & (1U << MODE3_CRCENB)))
1010 {
1011 mode3IsWrittenCorrect = 1;
1012 break;
1013 }
1014 }
1015 else continue;
1016 }
1017
1018 if (!mode3IsWrittenCorrect)
1019 while (1)
1020 { // Blink the RED LED forever
1021 HAL_GPIO_TogglePin(LED_ERROR_GPIO_Port, LED_ERROR_Pin);
1022 HAL_Delay(300);
1023 }
1024}
1025
1026//-----------------------------------------------------------------------------
1027
1028void ADS1260_ConversionFinished(void)
1029{
1030 ADS1260_ReadConversion();
1031 // ADS1260_StartConversion();
1032}
1033
1034//-----------------------------------------------------------------------------
Note: See TracBrowser for help on using the repository browser.