Electronic Load 1.0 Programmable Constant Current Sink

Functions | Variables
spi.c File Reference

Routines for SPI connected peripherals (ADC, DAC and LEDs) More...

Include dependency graph for spi.c:

## Functions
double | ADCGetAs (void)
| Gets the Ampere Seconds consumed. More...
double | ADCGetIavg (void)
| Returns the averaged Value for Load Current. More...
double | ADCGetIByVal (uint16_t iRaw, bool isHigh)
| Returns the Current for a given Value. More...
uint16_t | ADCGetIHighAvgRaw ()
| Returns the averaged Value for the Current. More...
uint16_t | ADCGetIhighLifeRaw ()
| Returns the Life Value for the Current. More...
uint16_t | ADCGetILowAvgRaw ()
| Returns the averaged Value for the Current. More...
uint16_t | ADCGetIlowLifeRaw ()
| Returns the Life Value for the Current. More...
double | ADCGetVavg (void)
| Returns the averaged Value for the Sink Voltage. More...
uint16_t | ADCGetVAvgRaw ()
| Returns the averaged Value for the Sink Voltage. More...
uint16_t | ADCGetVLifeRaw ()
| Returns the Life Value for the Sink Voltage. More...
void | CalcIMaxLookupTable (void)
| Calculates the Lookup Table for IMax. More...
void | CalcRChannel (void)
void | DACSetAmps (double i)
| Sets the DAC to a certain Current. More...
void | DACSetAmpsByStr (char *str)
| Sets the sink to the value of a string. More...
void | DACSetRaw (uint16_t value)
| Sets the raw Value of the DAC. More...
void | DACSetRawFast (uint16_t value)
| The same as DACSetRaw() but without updating the controls This function has been introduced to allow setting the DAC from ISRs. More...
| ISR (SPI_STC_vect)
| The Interrupt Service Routine for SPI. More...
void | SetHighCurrentMode (void)
| Sets High Current Mode. More...
void | SetLowCurrentMode (void)
| Sets Low Current Mode. More...
static void | SoaLimit ()
| Calculates the maximum allowable Current This function is designed to be fast enough to be executed from the SPI interrupt. It uses the lookup table soaIMaxLUT and a fast integer multiplication for temperature derating if the current range is high. If the actual DAC value is higher than allowed, it is reduced and the SOA error is set. In low current range no derating is necessary and this function does nothing. More...
void | SPIInit (void)
| Initializes the SPI Interface. More...
uint8_t | SpiSendAndReceiveByte (uint8_t b)
| Sends and receives a Byte over the SPI Bus. More...
void | SPISetLEDs (uint8_t mask)
| Sets the State of the 8 LEDs on the SPI-Shift-Register. More...

## Variables
volatile ADC_RcvStruct_t | ADC_RcvStruct
double | DACAmps
| Saves the value last set for the DAC. More...
uint16_t | derating
| Temperature Derating factor *65535. Maximum Power has to be derated by multiplication with derating. More...
uint16_t | soaIMaxLUT [128]
| Lookup Table for maximum DAC-Value versus ADC-Voltage. More...
volatile SPIADCData_t | SPIADCAvg
| Averaged Values over 16 measurements. These values may get up to 14 bits of precision. More...
volatile uint8_t | SPIPtr
| Is set by SPIStartADC() and counted down to zero by the ADC Interrupt. More...
SPI_XmtStruct_t | SPISendData ={{.array={0x00,0x00,0xa3,0x00,0x93,0x00,0x83}}}
| Send data buffer for the ADC. More...

## Detailed Description

Routines for SPI connected peripherals (ADC, DAC and LEDs)

Copyright
  Copyright (C) 2009 Robert Loos http://www.loosweb.de

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

## Function Documentation

## ◆ CalcIMaxLookupTable()

void CalcIMaxLookupTable | ( | void |  | ) |

Calculates the Lookup Table for IMax.

Here is the call graph for this function:

## ◆ SPISetLEDs()

void SPISetLEDs | ( | uint8_t | mask | ) |

Sets the State of the 8 LEDs on the SPI-Shift-Register.

Parameters

  mask | A Bitmask of the LEDs

Note
  The LEDs are not set immediately but on the next SPI interrupt covering the LED shift register. This may introduce a small delay.

## ◆ SetLowCurrentMode()

void SetLowCurrentMode | ( | void |  | ) |

Sets Low Current Mode.

## ◆ SetHighCurrentMode()

void SetHighCurrentMode | ( | void |  | ) |

Sets High Current Mode.

## ◆ SpiSendAndReceiveByte()

uint8_t SpiSendAndReceiveByte | ( | uint8_t | b | ) |

Sends and receives a Byte over the SPI Bus.

SPI implies the reception of a byte whenever one is sent. It depends on the hardware if it contains useful data.

Note
  This function blocks for the time of the transfer.

Parameters

  b | The Byte to transmit

Returns
  The received Byte

## ◆ DACSetRawFast()

void DACSetRawFast | ( | uint16_t | value | ) |
| inline

The same as DACSetRaw() but without updating the controls This function has been introduced to allow setting the DAC from ISRs.

Note
  Fast means the execution time. There is still a delay from the call of this function until the DAC is actually set!

Parameters

  value | The Value

Here is the caller graph for this function:

## ◆ DACSetRaw()

void DACSetRaw | ( | uint16_t | value | ) |

Sets the raw Value of the DAC.

Parameters

  value | The Value

Here is the call graph for this function:

## ◆ DACSetAmps()

void DACSetAmps | ( | double | i | ) |

Sets the DAC to a certain Current.

This function also switches the current range to high or low if the desired value is higher than rangeHighLimit or lower than rangeLowLimit.

Parameters

  i | The Current

Here is the call graph for this function:

## ◆ DACSetAmpsByStr()

void DACSetAmpsByStr | ( | char * | str | ) |

Sets the sink to the value of a string.

Parameters

  str | A Pointer to the string containing the value in amperes

Here is the call graph for this function:

## ◆ ADCGetIavg()

double ADCGetIavg | ( | void |  | ) |

Returns the averaged Value for Load Current.

This function honors the range setting and returns the value measured by the active sense resistor.

Returns
  The averaged Load Current in A

Here is the call graph for this function:

## ◆ ADCGetAs()

double ADCGetAs | ( | void |  | ) |

Gets the Ampere Seconds consumed.

Returns
  The As

Here is the call graph for this function:

## ◆ ADCGetIByVal()

double ADCGetIByVal | ( | uint16_t | iRaw,
|  | bool | isHigh
| ) |  |

Returns the Current for a given Value.

Parameters

  iRaw | The raw value from the ADC, normalized to 16 bits
  isHigh | True if the value represents a high current mode value

Returns
  The Load Current in A

## ◆ ADCGetVavg()

double ADCGetVavg | ( | void |  | ) |

Returns the averaged Value for the Sink Voltage.

Note
  The voltage over the sink may be reduced by cable and/or additional resistance and may not reflect the exact value of the source voltage.

Returns
  The Voltage over the Sink in V

## ◆ ADCGetIhighLifeRaw()

uint16_t ADCGetIhighLifeRaw | ( |  | ) |

Returns the Life Value for the Current.

The current is measured over the lower of the two shunts representing the high current range. The value is normalized to 16 bit unsigned int.

Returns
  The current in the range of 0000 to ffff

## ◆ ADCGetIlowLifeRaw()

uint16_t ADCGetIlowLifeRaw | ( |  | ) |

Returns the Life Value for the Current.

The current is measured over the higher of the two shunts representing the low current range. Note that this value is garbage if the resistor is shorted by the MOSFET. The value is normalized to 16 bit unsigned int.

Returns
  The current in the range of 0000 to ffff

## ◆ ADCGetVLifeRaw()

uint16_t ADCGetVLifeRaw | ( |  | ) |

Returns the Life Value for the Sink Voltage.

The value is normalized to 16 bit unsigned int.

Returns
  The Voltage over the Sink in the range of 0000 to ffff

## ◆ ADCGetIHighAvgRaw()

uint16_t ADCGetIHighAvgRaw | ( |  | ) |

Returns the averaged Value for the Current.

The current is measured over the lower of the two shunts representing the high current range. The value is normalized to 16 bit unsigned int.

Returns
  The current in the range of 0000 to ffff

## ◆ ADCGetILowAvgRaw()

uint16_t ADCGetILowAvgRaw | ( |  | ) |

Returns the averaged Value for the Current.

The current is measured over the higher of the two shunts representing the low current range. Note that this value is garbage if the resistor is shorted by the MOSFET. The value is normalized to 16 bit unsigned int.

Returns
  The current in the range of 0000 to ffff

## ◆ ADCGetVAvgRaw()

uint16_t ADCGetVAvgRaw | ( |  | ) |

Returns the averaged Value for the Sink Voltage.

The value is normalized to 16 bit unsigned int.

Returns
  The Voltage over the Sink in the range of 0000 to ffff

## ◆ SPIInit()

void SPIInit | ( | void |  | ) |

Initializes the SPI Interface.

Here is the call graph for this function:

## ◆ SoaLimit()

static void SoaLimit | ( |  | ) |
| inlinestatic

Calculates the maximum allowable Current This function is designed to be fast enough to be executed from the SPI interrupt. It uses the lookup table soaIMaxLUT and a fast integer multiplication for temperature derating if the current range is high. If the actual DAC value is higher than allowed, it is reduced and the SOA error is set. In low current range no derating is necessary and this function does nothing.

Here is the call graph for this function:
Here is the caller graph for this function:

## ◆ CalcRChannel()

void CalcRChannel | ( | void |  | ) |

Here is the call graph for this function:

## ◆ ISR()

ISR | ( | SPI_STC_vect |  | ) |

The Interrupt Service Routine for SPI.

It collects the Data of the ADC and builds up averages. The life 12-bit value read out of the ADC starts at bit 15 in the receive struct. By averaging 16 values we gain additional 2 bits of accuracy. So the average value will be a 16-bit FSR-Value where the 2 LSBs are garbage and thus reflect 14 bits. It will occur at a frequency of ~12.5kHz with a 7.3728MHz crystal.

Here is the call graph for this function:

## Variable Documentation

## ◆ SPISendData

SPI_XmtStruct_t SPISendData ={{.array={0x00,0x00,0xa3,0x00,0x93,0x00,0x83}}}

Send data buffer for the ADC.

Each conversion needs 3 bytes to send. The first one is the command byte followed by two "0"-bytes in which the ADC sends its result. Command byte is composed as:
S Start bit, always 1
A2-A0 Channel address
X Dummy bit
SGL/DIF 1 for single ended, 0 for differential
PD1-0 Power down mode
Simply by sending 7 Bytes all conversions for the three channels we use are done. The last byte is a dummy byte necessary to get the last ADC result.

## ◆ ADC_RcvStruct

volatile ADC_RcvStruct_t ADC_RcvStruct

## ◆ SPIADCAvg

volatile SPIADCData_t SPIADCAvg

Averaged Values over 16 measurements. These values may get up to 14 bits of precision.

## ◆ SPIPtr

volatile uint8_t SPIPtr

Is set by SPIStartADC() and counted down to zero by the ADC Interrupt.

## ◆ derating

uint16_t derating

Temperature Derating factor *65535. Maximum Power has to be derated by multiplication with derating.

## ◆ soaIMaxLUT

uint16_t soaIMaxLUT[128]

Lookup Table for maximum DAC-Value versus ADC-Voltage.

This table contains the maximum DAC-Values for the high byte of a given ADC voltage result. So the ADC interrupt can easily decide to reduce the current with each measurement if the SOA is violated.
This table has to be calculated by CalcIMaxLookupTable() on system startup!

Note
  For now, we keep this as uint16_t but 256 values with two bytes each make a quarter of the controllers RAM. We could reduce this to only the upper byte of the DAC at the cost of usable SOA area. Further reduction is possible by using less bits of the ADC value.
  Note also that the values still have to be degraded according to the case (heatsink) temperature!

## ◆ DACAmps

double DACAmps

Saves the value last set for the DAC.