// ----------------------------------------------------------------------------- /// @file MAX5715.c /// @brief Description // ----------------------------------------------------------------------------- // Micro-Key bv // Industrieweg 28, 9804 TG Noordhorn // Postbus 92, 9800 AB Zuidhorn // The Netherlands // Tel: +31 594 503020 // Fax: +31 594 505825 // Email: support@microkey.nl // Web: www.microkey.nl // ----------------------------------------------------------------------------- /// $Revision$ /// $Author$ /// $Date$ // (c) 2017 Micro-Key bv // ----------------------------------------------------------------------------- /// @file MAX5715.c /// @ingroup {group_name} // ----------------------------------------------------------------------------- // Include files // ----------------------------------------------------------------------------- #include "Logger.h" #include "MAX5715.h" #include "spi.h" // ----------------------------------------------------------------------------- // Constant and macro definitions // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // Type definitions // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // File-scope variables // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- // Function declarations // ----------------------------------------------------------------------------- static ErrorStatus channelWrite(const struct DACDevice* self, uint32_t voltage); static uint32_t channelReadback (const struct DACDevice* self); // ----------------------------------------------------------------------------- // Function definitions // ----------------------------------------------------------------------------- ErrorStatus MAX5715_construct(struct MAX5715* self, const struct IODevice* device) { ErrorStatus returnValue = SUCCESS; int loopCounter; if (!self->initialized) { if (device != NULL) { for (loopCounter = 0; loopCounter < MAX5715_NUMBER_OF_DACS; loopCounter++) { self->dac[loopCounter].initialized = false; } self->device = device; self->initialized = true; } else { returnValue = ERROR; } } else { returnValue = ERROR; } return returnValue; } void MAX5715_destruct(struct MAX5715* self) { self->device = NULL; } ErrorStatus MAX5715_getSpiParameters(struct SpiParameters* parameters) { ErrorStatus returnValue = SUCCESS; if ((configCPU_CLOCK_HZ / 2) < MAX5715_SPI_MAX_CLK_HZ) { parameters->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2; } else if ((configCPU_CLOCK_HZ / 4) < MAX5715_SPI_MAX_CLK_HZ) { parameters->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; } else if ((configCPU_CLOCK_HZ / 8) < MAX5715_SPI_MAX_CLK_HZ) { parameters->SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8; } else { // The CPU clock is too high. The pre-scaler has a max of 256. A clock higher than 25,6 MHz // results in a SPI CLK higher than 100 kHz, which is the max of the display returnValue = ERROR; } if (returnValue == SUCCESS) { // SPI pre-scaler was no problem - assign the remaining parameters parameters->SPI_CPHA = MAX5715_SPI_CPHA; parameters->SPI_CPOL = MAX5715_SPI_CPOL; parameters->SPI_CRCPolynomial = MAX5715_SPI_CRCPolynomial; parameters->SPI_DataSize = MAX5715_SPI_DataSize; parameters->SPI_Direction = MAX5715_SPI_Direction; parameters->SPI_FirstBit = MAX5715_SPI_FirstBit; parameters->SPI_Mode = MAX5715_SPI_Mode; parameters->SPI_NSS = MAX5715_SPI_NSS; parameters->SPI_NSS_internal = MAX5715_SPI_NSS_INTERNAL; parameters->rxQueueSize = MAX5715_SPI_RX_QUEUE; parameters->txQueueSize = MAX5715_SPI_TX_QUEUE; } return returnValue; } ErrorStatus MAX5715_sendCommand(const struct MAX5715* self, uint8_t command, uint16_t data) { char buffer[3] = {(char)command, (char)(data >> 4), (char)((data << 4) & 0x00F0)}; return IODevice_write(self->device, buffer, 3); } ErrorStatus MAX5715Channel_construct(struct MAX5715_DAC* self, struct MAX5715* parent, size_t id) { ErrorStatus returnValue = SUCCESS; if (id < MAX5715_NUMBER_OF_DACS) { // Check that the parent has no channel already initialized on that ID if ((!parent->dac[id].initialized) && (parent->initialized)) { if (!self->initialized) { parent->dac[id] = *self; self->id = id; self->parent = parent; self->value = 0; self->initialized = true; if (returnValue == SUCCESS) { returnValue = DACDevice_construct(&self->dacDevice, channelWrite, channelReadback, MAX5715_RESOLUTION_IN_BITS); } } else { returnValue = ERROR; } } else { returnValue = ERROR; } } else { returnValue = ERROR; } return returnValue; } ErrorStatus MAX5715Channel_setValue(struct MAX5715_DAC* self, uint16_t value) { ErrorStatus returnValue = SUCCESS; if (self != NULL) { if ((self->initialized) && (self->parent->initialized)) { ///TODO value must be verified with DAC device boarders (add limits to class) self->value = value; // Send data to CODEn register MAX5715_writeCODEn(self->parent, self->id, self->value); // Load CODEn register to DAC output MAX5715_writeLOADn(self->parent, self->id); } else { returnValue = ERROR; } } else { returnValue = ERROR; } return returnValue; } static ErrorStatus channelWrite(const struct DACDevice* self, uint32_t voltage) { if (voltage > ((1 << MAX5715_RESOLUTION_IN_BITS) - 1)) { voltage = ((1 << MAX5715_RESOLUTION_IN_BITS) - 1); } // MASK the uint32_t DAC value (voltage) with the resolution of the MAX5715 DAC return MAX5715Channel_setValue((struct MAX5715_DAC*)self, (((1 << MAX5715_RESOLUTION_IN_BITS) - 1) & voltage)); } static uint32_t channelReadback (const struct DACDevice* self) { struct MAX5715_DAC* tempDac = (struct MAX5715_DAC*)self; return tempDac->value; }