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

Last change on this file since 74 was 73, checked in by f.jahn, 32 hours ago

Delta Sigma ADC auf 10Channel geändert.

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