mirror of https://github.com/rusefi/rusefi-1.git
143 lines
3.0 KiB
C++
143 lines
3.0 KiB
C++
/*
|
|
* @file mcp3208.cpp
|
|
* @brief MCP3208 external ADC chip implementation. Not really used right now.
|
|
*
|
|
* @date Aug 12, 2013
|
|
* @author Andrey Belomutskiy, (c) 2012-2020
|
|
*/
|
|
|
|
#include "global.h"
|
|
#include "os_access.h"
|
|
|
|
#if EFI_MCP_3208
|
|
#include "mcp3208.h"
|
|
#include "pin_repository.h"
|
|
|
|
McpAdcState *hack;
|
|
|
|
static int adcEventCounter = 0;
|
|
static int adcErrorCounter = 0;
|
|
|
|
static int getValue(McpAdcState *state, int channel) {
|
|
return state->results[channel] & 4095;
|
|
}
|
|
|
|
int getMcp3208adc(int channel) {
|
|
return getValue(hack, channel);
|
|
}
|
|
|
|
static int getNextChannel(void) {
|
|
return adcEventCounter % 2;
|
|
}
|
|
|
|
static void spiCallback(SPIDriver *spip) {
|
|
spiUnselectI(spip);
|
|
adcEventCounter++;
|
|
|
|
McpAdcState *state = hack;
|
|
|
|
int withError = 0;
|
|
|
|
if (state->rx_buff[0] != 255) {
|
|
withError = 1;
|
|
//fatal("ADC: first byte");
|
|
}
|
|
|
|
if ((state->rx_buff[1] & 0xE0) != 0xE0) {
|
|
withError = 1;
|
|
//fatal("ADC: second byte");
|
|
}
|
|
|
|
if (!withError) {
|
|
// unsigned char upperByte = state->rx_buff[1] & 0b00001111;
|
|
int result = (state->rx_buff[0] << 16) + (state->rx_buff[1] << 8) + state->rx_buff[2];
|
|
state->results[state->requestedChannel] = result;
|
|
} else {
|
|
adcErrorCounter++;
|
|
}
|
|
|
|
requestAdcValueI(state, getNextChannel());
|
|
}
|
|
|
|
static const SPIConfig spicfg = { spiCallback,
|
|
/* HW dependent part.*/
|
|
MCP3208_CS_PORT,
|
|
MCP3208_CS_PIN,
|
|
//SPI_CR1_MSTR |
|
|
SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_BR_2
|
|
// SPI_CR1_BR_1 | SPI_CR1_BR_2
|
|
};
|
|
|
|
static void createRequest(McpAdcState *state, int channel) {
|
|
efiAssertVoid(CUSTOM_ERR_6680, channel < 8, "Invalid ADC channel");
|
|
|
|
state->requestedChannel = channel;
|
|
|
|
state->tx_buff[0] = 0x06 + (channel >> 2);
|
|
state->tx_buff[1] = (channel & 3) << 6;
|
|
}
|
|
|
|
void requestAdcValue(McpAdcState *state, int channel) {
|
|
createRequest(state, channel);
|
|
|
|
spiSelect(state->driver);
|
|
spiStartExchange(state->driver, 3, state->tx_buff, state->rx_buff);
|
|
// SPI unselect is in the callback
|
|
}
|
|
|
|
void requestAdcValueI(McpAdcState *state, int channel) {
|
|
createRequest(state, channel);
|
|
|
|
spiSelectI(state->driver);
|
|
spiStartExchangeI(state->driver, 3, state->tx_buff, state->rx_buff);
|
|
// SPI unselect is in the callback
|
|
}
|
|
|
|
void adc_in_out(McpAdcState *state) {
|
|
|
|
// chThdSleepMilliseconds(10);
|
|
|
|
int result = state->results[0];
|
|
|
|
// int v = result;
|
|
unsigned r = 0;
|
|
//
|
|
// while (v >>= 1)
|
|
// r++;
|
|
//
|
|
// unsigned int f;
|
|
// if (r < 12) {
|
|
// f = -1;
|
|
// } else {
|
|
// f = result >> (r - 12);
|
|
// f = f & 4095;
|
|
// }
|
|
|
|
int errRatio = 1000 * adcErrorCounter / adcEventCounter;
|
|
|
|
print("c/e %7d/%7d/%4d result %5d r=%d ", adcEventCounter, adcErrorCounter, errRatio, result, r);
|
|
|
|
unsigned int f0 = getValue(state, 0);
|
|
print("ch0=%d adj %d ", f0, f0 * 5000 / 4096);
|
|
unsigned int f1 = getValue(state, 1);
|
|
print("ch1=%d adj %d\r\n", f1, f1 * 5000 / 4096);
|
|
}
|
|
|
|
void init_adc_mcp3208(McpAdcState *state, SPIDriver *driver) {
|
|
|
|
// initSpiModules();
|
|
|
|
state->driver = driver;
|
|
state->tx_buff[2] = 0;
|
|
|
|
hack = state;
|
|
|
|
todo: convert to new API, todo: array of CS
|
|
mySetPadMod("ext adc chip select", MCP3208_CS_PORT, MCP3208_CS_PIN, PAL_STM32_MODE_OUTPUT);
|
|
|
|
|
|
spiStart(driver, &spicfg);
|
|
}
|
|
|
|
#endif /* EFI_MCP_3208 */
|