|
|
@@ -18,79 +18,35 @@
|
|
|
- Convert Analog output to voltage in Volts: Convert_ADC_To_Voltage()
|
|
|
- Commented out interrupts for the time being.
|
|
|
- Adding code for Pi to READ ADC voltages in mV.
|
|
|
- -
|
|
|
+
|
|
|
+ 27.02.2025:
|
|
|
+ DAC function to write to Channel A in Fast Mode and return the Analog output
|
|
|
*/
|
|
|
|
|
|
|
|
|
#include "ti/devices/msp/peripherals/hw_dac12.h"
|
|
|
+#include "ti/driverlib/dl_adc12.h"
|
|
|
#include "ti/driverlib/dl_gpio.h"
|
|
|
#include "ti/driverlib/dl_i2c.h"
|
|
|
#include "ti/driverlib/m0p/dl_core.h"
|
|
|
#include "ti_msp_dl_config.h"
|
|
|
#include "ti/comm_modules/i2c/controller/i2c_comm_controller.h"
|
|
|
-#include<stdint.h>
|
|
|
-#include<stdio.h>
|
|
|
+#include <stdint.h>
|
|
|
+#include <stdio.h>
|
|
|
+#include "multiplexer.h"
|
|
|
+#include "adc.h"
|
|
|
+#include "dac.h"
|
|
|
|
|
|
I2C_Instance gI2C;
|
|
|
+I2C_ResponseInfo gResponse;
|
|
|
+
|
|
|
+
|
|
|
+#define NUM_BATTERY_SLOT (1)
|
|
|
+uint16_t battery_slots[NUM_BATTERY_SLOT];
|
|
|
+uint8_t battery_status[1]= {0x02};
|
|
|
+
|
|
|
+
|
|
|
|
|
|
-/*MULTIPLEXER SECTION:*/
|
|
|
-
|
|
|
-/*Multiplexer Address*/
|
|
|
-#define MULTIPLEXER_I2C_ADDR (0x70)
|
|
|
-
|
|
|
-/*Multiplexer channel*/
|
|
|
-#define ADC_I2C_CHANNEL (0x01)
|
|
|
-
|
|
|
-/*****************DAC*********************/
|
|
|
-
|
|
|
-/*Fast write command for DAC*/
|
|
|
-#define FAST_WRITE_COMMAND 0x00
|
|
|
-#define MULTI_WRITE 0x40
|
|
|
-#define SINGLE_WRITE 0x58
|
|
|
-#define SEQ_WRITE 0x50
|
|
|
-#define VREF_CMD 0x80
|
|
|
-#define GAIN_CMD 0xC0
|
|
|
-#define PWR_DWN_CMD 0xA0
|
|
|
-
|
|
|
-//DAC Channel Selection
|
|
|
-typedef enum{
|
|
|
- DAC_A = 0,
|
|
|
- DAC_B,
|
|
|
- DAC_C,
|
|
|
- DAC_D
|
|
|
-} DAC_CH;
|
|
|
-
|
|
|
-typedef enum{
|
|
|
- VREF_VDD= 0,
|
|
|
- VREF_INTERNAL= 1
|
|
|
-}VREF_SELECTION;
|
|
|
-
|
|
|
-typedef enum{
|
|
|
- GAIN_X1= 0,
|
|
|
- GAIN_X2= 1
|
|
|
-}GAIN_SELECTION;
|
|
|
-
|
|
|
-typedef enum{
|
|
|
- PD_NORMAL=0,
|
|
|
- PD_GND_1KOHM= 1,
|
|
|
- PD_GND_100KOHM= 2,
|
|
|
- PD_GND_500KOHM= 3
|
|
|
-}PWR_DOWN_SELECTION;
|
|
|
-
|
|
|
-// Structure to Hold DAC Register Data
|
|
|
-typedef struct {
|
|
|
- VREF_SELECTION vref;
|
|
|
- PWR_DOWN_SELECTION pd;
|
|
|
- GAIN_SELECTION gain;
|
|
|
- uint16_t data;
|
|
|
-} DACRegisterData;
|
|
|
-
|
|
|
-// Create Global Storage for DAC Values
|
|
|
-DACRegisterData read_reg_[4]; // Holds Active Register Values
|
|
|
-DACRegisterData read_eep_[4]; // Holds EEPROM Stored Values
|
|
|
-
|
|
|
-
|
|
|
-/***********************/
|
|
|
|
|
|
/*
|
|
|
|
|
|
@@ -110,31 +66,35 @@ Calculation for V(IN)= (ADC Value/2^ (Resolution-1))* V(REF)
|
|
|
- Register address where ADC result would be stored
|
|
|
*/
|
|
|
|
|
|
-#define VREF 2.048
|
|
|
+//#define VREF 2.048
|
|
|
// address register for ADC Voltage Read:
|
|
|
-#define ADC_REGISTER 0x10
|
|
|
+//#define ADC_REGISTER 0x10
|
|
|
+/*****************/
|
|
|
/*Register for the MCU*/
|
|
|
#define REGISTER_SIZE 256
|
|
|
-#define I2C_BUFFER_SIZE (16)
|
|
|
-//#define DAC12_REF_VOLTAGE_mV (2500)
|
|
|
-
|
|
|
uint8_t registers[REGISTER_SIZE]= {1, 2, 3, 4, 5};
|
|
|
|
|
|
-/* Buffers for data exchange with Pi*/
|
|
|
-uint16_t gRxBuffer[I2C_BUFFER_SIZE]= {0};
|
|
|
-uint16_t gTxBuffer[I2C_BUFFER_SIZE]={0};
|
|
|
|
|
|
-/*Counter for data length and bytes*/
|
|
|
+/*Counters for TX length and bytes sent*/
|
|
|
uint32_t gTxLen, gTxCount;
|
|
|
+/* Counters for RX length and bytes sent*/
|
|
|
uint32_t gRxLen, gRxCount;
|
|
|
|
|
|
-volatile I2C_CommandInfo gCommand;
|
|
|
-
|
|
|
-I2C_ResponseInfo gResponse;
|
|
|
+/* Boolean to know when a stop command was issued */
|
|
|
+bool gStopReceived = false;
|
|
|
|
|
|
+/* ADC variables:
|
|
|
+ * gADCResult is the adc result taken from the Memory Register
|
|
|
+ * NumberOfADCSamples is the count of total ADC samples to keep track for the gTxResult buffer
|
|
|
+ */
|
|
|
|
|
|
-volatile bool gSendCommand = true;
|
|
|
-volatile bool newMeasurementAvailable = false;
|
|
|
+//uint16_t gADCResult;
|
|
|
+//uint8_t gNumberOfADCSamples = 0;
|
|
|
+//bool gCheckADC = false;
|
|
|
+//volatile I2C_CommandInfo gCommand;
|
|
|
+//I2C_ResponseInfo gResponse;
|
|
|
+//volatile bool gSendCommand = true;
|
|
|
+//volatile bool newMeasurementAvailable = false;
|
|
|
|
|
|
|
|
|
uint8_t gTxData[MAX_DATA_SIZE] = {0} ;
|
|
|
@@ -167,137 +127,10 @@ void I2C_scanBus() {
|
|
|
printf("I2C Scan Complete!\n");
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
-Multiplexer TCA9548A:
|
|
|
-Address:0x70
|
|
|
-The TCA9548A is example of a single-register device, which is controlled via I2C commands. Since it has 1 bit to enable or disable a channel, there is only 1 register
|
|
|
-needed, and the controller merely writes the register data after the target address, skipping the register number.
|
|
|
-ADC connected to channel 0
|
|
|
-Both SDA and SL lines of the multiplexer is connected to VIN through pull-up resistors
|
|
|
-The following is the general procedure for a controller to access a target device:
|
|
|
-1. If a controller wants to send data to a target:
|
|
|
- • Controller-transmitter sends a START condition and addresses the target-receiver.
|
|
|
- • Controller-transmitter sends data to target-receiver.
|
|
|
- • Controller-transmitter terminates the transfer with a STOP condition.
|
|
|
-2. If a controller wants to receive or read data from a target:
|
|
|
- • Controller-receiver sends a START condition and addresses the target-transmitter.
|
|
|
- • Controller-receiver sends the requested register to read to target-transmitter.
|
|
|
- • Controller-receiver receives data from the target-transmitter.
|
|
|
- • Controller-receiver terminates the transfer with a STOP condition.
|
|
|
-The TCA9548A is example of a single-register device, which is controlled via I2C commands. Since it has 1 bit to enable or disable a channel,
|
|
|
-there is only 1 register needed, and the controller merely writes the register data after the target address, skipping the register number.
|
|
|
-*/
|
|
|
-
|
|
|
-/*Function for Multiplexer*/
|
|
|
-
|
|
|
-void Multiplexer_SelectChannel(uint8_t channel)
|
|
|
-{
|
|
|
- uint8_t data = channel;
|
|
|
- printf("Selecting Multiplexer Channel: 0x%02X\n", data);
|
|
|
-
|
|
|
- // Ensure bus is idle before starting communication
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
-
|
|
|
- // SEND Command to Multiplexer
|
|
|
- DL_I2C_startControllerTransfer(I2C_controller_INST, MULTIPLEXER_I2C_ADDR, DL_I2C_CONTROLLER_DIRECTION_TX, 1);
|
|
|
- DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &data, 1);
|
|
|
-
|
|
|
- // **Ensure STOP condition is sent**
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
-
|
|
|
- // **Slightly Increase Delay for Multiplexer to Process Command**
|
|
|
- delay_cycles(30000);
|
|
|
-
|
|
|
- // Verify Multiplexer Response:
|
|
|
- uint8_t response= 0x00;
|
|
|
- DL_I2C_startControllerTransfer(I2C_controller_INST, MULTIPLEXER_I2C_ADDR, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
|
|
|
-
|
|
|
- // Wait for a response from the multiplexer
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
- response = DL_I2C_receiveControllerData(I2C_controller_INST);
|
|
|
-
|
|
|
- // **Debug: Print Expected vs. Received Response**
|
|
|
- printf("Multiplexer Response: 0x%02X (Expected: 0x%02X)\n", response, data);
|
|
|
-
|
|
|
- // **CHECK FOR ADDRESS ACKNOWLEDGMENT**
|
|
|
- /*if (!(DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR)) {
|
|
|
- printf("Multiplexer detected at 0x70.\n");
|
|
|
- return;
|
|
|
- } else{
|
|
|
- printf("ERROR: Multiplexer (0x70) detected.\n");
|
|
|
- }*/
|
|
|
-
|
|
|
- // Wait for transaction completion
|
|
|
- //while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
-
|
|
|
- if(response != data){
|
|
|
- printf("ERROR: Multiplexer did not set the correct channel!\n");
|
|
|
- // **Retry Mechanism: Attempt to Set the Channel Again**
|
|
|
- delay_cycles(10000);
|
|
|
- Multiplexer_SelectChannel(channel);
|
|
|
- } else {
|
|
|
- printf("Multiplexer Active Channel: 0x%X\n", data);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
-/*
|
|
|
-CONFIGURATION REGISTER:
|
|
|
-8-bit wide configuration register to select for: input channel, conversion mode, conversion rate, and PGA gain.
|
|
|
-Device allows the user to changethe operating condition of the device:
|
|
|
|
|
|
-*/
|
|
|
|
|
|
-uint8_t Construct_Config_Byte(uint8_t channel, uint8_t resolution, bool continuous, uint8_t gain) {
|
|
|
|
|
|
- uint8_t config = 0;
|
|
|
-
|
|
|
-
|
|
|
- config |= ((channel - 1) << 5); // Channel Selection (Bits 6-5)
|
|
|
-
|
|
|
- if (continuous) config |= (1 << 4); // Continuous Mode (Bit 4)
|
|
|
-
|
|
|
- switch (resolution) {
|
|
|
- case 12: config |= (0b00 << 2); break;
|
|
|
- case 14: config |= (0b01 << 2); break;
|
|
|
- case 16: config |= (0b10 << 2); break;
|
|
|
- case 18: config |= (0b11 << 2); break;
|
|
|
- default: printf("ERROR: Invalid Resolution!\n"); return 0;
|
|
|
- }
|
|
|
-
|
|
|
- switch (gain) {
|
|
|
- case 1: config |= (0b00); break;
|
|
|
- case 2: config |= (0b01); break;
|
|
|
- case 4: config |= (0b10); break;
|
|
|
- case 8: config |= (0b11); break;
|
|
|
- default: printf("ERROR: Invalid Gain!\n"); return 0;
|
|
|
- }
|
|
|
-
|
|
|
- return config;
|
|
|
-}
|
|
|
-
|
|
|
-/* Tansmit Data from MCU to ADC: Function to SET configuration to ADC over I2C*/
|
|
|
-
|
|
|
-void SetConfiguration(uint8_t channel, uint8_t resolution, bool mode, uint8_t gain) {
|
|
|
- // **Step 1: Construct Configuration Byte**
|
|
|
- uint8_t config_byte = Construct_Config_Byte(channel, resolution, mode, gain);
|
|
|
-
|
|
|
- printf("Writing Config: 0x%02X to ADC (0x%X)...\n", config_byte, DEF_TARGET_ADDR_ADC);
|
|
|
-
|
|
|
- // **Step 2: Wait for I2C Bus to be Free**
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
-
|
|
|
- // **Step 3: Start I2C Write Transaction**
|
|
|
- DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_ADC, DL_I2C_CONTROLLER_DIRECTION_TX, 1);
|
|
|
-
|
|
|
- // **Step 4: Load Configuration Byte into TX FIFO**
|
|
|
- DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &config_byte, 1);
|
|
|
-
|
|
|
- // **Step 5: Ensure STOP Condition is Sent**
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
- printf("Configuration Byte: 0x%02X\n", config_byte);
|
|
|
- printf("Configuration Sent Successfully!\n");
|
|
|
-}
|
|
|
|
|
|
/*Function to get the RDY bit from ADC*/
|
|
|
|
|
|
@@ -316,362 +149,12 @@ bool Check_ADC_Ready()
|
|
|
|
|
|
*/
|
|
|
|
|
|
- DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_ADC, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
|
|
|
+ DL_I2C_startControllerTransfer(I2C_controller_INST, ADC_TARGET_BASE_ADDRESS, DL_I2C_CONTROLLER_DIRECTION_RX, 1);
|
|
|
config_byte = DL_I2C_receiveControllerData(I2C_controller_INST);
|
|
|
return (config_byte & 0x80) == 0; // Check if RDY bit is cleared in bit 7
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-/*
|
|
|
-Function to read ADC DATA: This function simply retrieves the ADC raw digital output as 16-bit signed integer.
|
|
|
-* The value returned is not yet converted to VOLTAGE.
|
|
|
-* adc_data[2]: Buffer with an array of size 2, to store two bytes of ADC data.
|
|
|
-* Since, the ADC output consists of two 8-bit bytes:
|
|
|
-* - adc_data[0] (MSB)
|
|
|
-* - adc_data[1] (LSB)
|
|
|
-* Next, we verify if the the I2C bus is busy using the function in the driverlib: DL_I2C_get ControllerStatus
|
|
|
-* - Prevents collisions by ensuring no two I2C device is using the same bus before initializing.
|
|
|
-* BEGIN I2C READ operation to request 2 bytes from the ADC-> DL_I2C_startControllerTransfer()
|
|
|
-* Parameters:
|
|
|
- - I2C_controller_INST: Refererence to the I2C instance bring used.
|
|
|
- - DEF_TARGET_ADDR_ADC: Address of the ADC
|
|
|
- - DL_I2C_CONTROLLER_DIRECTION_RX: Indicates that we want to receive the data from ADC
|
|
|
- - 2: Specifies that we expect 2 bytes from the ADC
|
|
|
-* WAIT for the data to be received: (DL_I2C_getControllerStatus())
|
|
|
- - Waits until the ADC sends the data over I2C.
|
|
|
- - Ensures that the data transfer is complete before proceeding.
|
|
|
-* READ the two bytes of ADc Data:
|
|
|
- - adc_data[0] : MSB
|
|
|
- - adc_data[1] : LSB
|
|
|
- - adc_data[2] : config_bytes
|
|
|
- ADC sends its 16-bit value in two parts over 8-bit I2C data frames.
|
|
|
-* COMBINE the two bytes into 16-bit Integer:
|
|
|
- - Shifts the MSB(first byte) left by 8 bits to make space for LSB.
|
|
|
- - Performs a bitwise OR operation to combine MSB and LSB into a single 16-bit number.
|
|
|
-* PRINT HEXADEC and DECIMAL format for DEBUGGING.
|
|
|
-* Output code is in binary and is proportional to the Input Voltage and PGA settings.
|
|
|
-* From the datasheet: https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/22226a.pdf
|
|
|
- - Equation 4.4 is being used to convert the output codes to input voltage
|
|
|
-*/
|
|
|
-
|
|
|
-int16_t Read_ADC_Data(uint8_t resolution)
|
|
|
-{
|
|
|
- uint8_t adc_data[3] = {0}; // Buffer for ADC data (MSB, LSB, Config Byte)
|
|
|
- int16_t raw_adc = 0;
|
|
|
-
|
|
|
- printf("Reading ADC Data from MCP3428...\n");
|
|
|
-
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
-
|
|
|
- // Determine bytes to read
|
|
|
- printf("Resolution for reading ADC is %d\n", resolution);
|
|
|
-
|
|
|
- delay_cycles(10000);
|
|
|
-
|
|
|
- // Request 3 Bytes from ADC**
|
|
|
- DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_ADC, DL_I2C_CONTROLLER_DIRECTION_RX, 3);
|
|
|
-
|
|
|
- // Read Data into Buffer**
|
|
|
- int i = 0;
|
|
|
- while(i<3){
|
|
|
- while (DL_I2C_isControllerRXFIFOEmpty(I2C_controller_INST));
|
|
|
- printf("Loop no: %d\n",i);
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
- adc_data[i] = DL_I2C_receiveControllerData(I2C_controller_INST);
|
|
|
- printf("Received Byte[%d]: 0x%02X\n", i, adc_data[i]);
|
|
|
- i++;
|
|
|
- }
|
|
|
- newMeasurementAvailable = true;
|
|
|
-
|
|
|
- /*Combining MSB and LSB for ADC output*/
|
|
|
- raw_adc= adc_data[0] << 8 | adc_data[1];
|
|
|
- printf("Raw ADC Value: 0x%0X (%d)\n", raw_adc, raw_adc);
|
|
|
- //printf("Resolution: %d \n", resolution_bits );
|
|
|
- return raw_adc;
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/* Function to Convert ADC Reading to Voltage */
|
|
|
-float Convert_ADC_To_Voltage(int16_t adc_value, uint8_t resolution, uint8_t gain) {
|
|
|
- if (!newMeasurementAvailable)
|
|
|
- { return -1; }
|
|
|
- float voltage= 0;
|
|
|
- float LSB= 0;
|
|
|
- uint32_t max_adc_value= 1;
|
|
|
-
|
|
|
- switch (resolution) {
|
|
|
- case 12: // 12-bit
|
|
|
- max_adc_value = 2048;
|
|
|
- break;
|
|
|
- case 14: // 14-bit
|
|
|
- max_adc_value = 8192;
|
|
|
- break;
|
|
|
- case 16: // 16-bit
|
|
|
- max_adc_value = 32768;
|
|
|
- break;
|
|
|
- case 18: // 18-bit
|
|
|
- max_adc_value = 131072;
|
|
|
- break;
|
|
|
- default:
|
|
|
- printf("Error: Unknown ADC Resolution!\n");
|
|
|
- return 0.0;
|
|
|
- }
|
|
|
-
|
|
|
- /*Considering that MSB is always 0*/
|
|
|
- printf("Max Resolution %d\n", max_adc_value);
|
|
|
- LSB= ((VREF)/max_adc_value);
|
|
|
- printf("LSB: %f\n", LSB);
|
|
|
- float inputVoltage= ((float)adc_value*(LSB/gain));
|
|
|
-
|
|
|
-
|
|
|
- /*Formula for ADC to Voltage Conversion*/
|
|
|
- /*voltage = ((float)adc_value / max_adc_value) * VREF;
|
|
|
-
|
|
|
- printf("Converted Voltage: %.2f V\n", voltage);*/
|
|
|
-
|
|
|
- printf("Input Voltage Measured: %.2f V\n", inputVoltage);
|
|
|
-
|
|
|
- /*To send the voltage to Pi in milliVolts*/
|
|
|
- uint16_t voltage_mV= inputVoltage * 1000;
|
|
|
-
|
|
|
- /*Storing ADC voltages in mVolts */
|
|
|
- registers[ADC_REGISTER] = (voltage_mV>>8) & 0xFF; //Highest Byte
|
|
|
- registers[ADC_REGISTER + 1] = (voltage_mV) & 0xFF; //Lowest Byte
|
|
|
- newMeasurementAvailable = false;
|
|
|
- printf("ADC Voltage Stored %d mV in MCU: MSB= 0x%02X, LSB= 0x%02X\n", voltage_mV, registers[ADC_REGISTER], registers[ADC_REGISTER + 1]);
|
|
|
- return voltage;
|
|
|
-}
|
|
|
-
|
|
|
-/*
|
|
|
-DAC Configuration function: Tx to DAC channel
|
|
|
-DAC expects 3 bytes from the channel:
|
|
|
-Byte 0: write command + channel_selection
|
|
|
-Byte 1: configuration + high byte of DAC
|
|
|
-Byte 2: low byte of DAC
|
|
|
-*/
|
|
|
-/*bool SET_CHANNEL_VALUE(DAC_CH ch, uint16_t new_value, VREF_SELECTION new_vref, GAIN_SELECTION new_gain, PWR_DOWN_SELECTION new_pwr_dwn, bool udac){
|
|
|
- uint8_t output_buffer[8];
|
|
|
-
|
|
|
- //Build the setter header (Address) -> 01000 DAC0 DAC1 DAC2
|
|
|
-
|
|
|
- uint8_t channel_write_cmd = FAST_WRITE_COMMAND; //0x00; FAST write mode
|
|
|
- //channel_write_cmd |= (ch << 1); //SET DAC channel
|
|
|
- //channel_write_cmd|= udac; // if udac is SET to 0; VOUT is updated after the 4th byte's ACK is issued
|
|
|
-
|
|
|
- output_buffer[0]= channel_write_cmd;
|
|
|
-
|
|
|
- // Construct the 12bit DAC value with the configuration settings
|
|
|
- // For Fast write command it does not gives VREF:
|
|
|
- // PD1 PD2 Gx D11 D10 D9 D8 [Byte 1]
|
|
|
- // D7 D6 D5 D4 D3 D2 D1 D0 [Byte 2]
|
|
|
-
|
|
|
- //new_value &= 0x0FFF; //Ensure only 12 bits are set
|
|
|
- //new_value |= (new_vref << 15);
|
|
|
- new_value |= (new_pwr_dwn << 13);
|
|
|
- //new_value |= (new_gain << 12);
|
|
|
- new_value |= new_value<< 9;
|
|
|
- new_value |= new_value<< 8;
|
|
|
-
|
|
|
- output_buffer[1]= new_value >> 8; //Upper Byte
|
|
|
- output_buffer[2]= new_value & 0xFF; //Lower Byte
|
|
|
-
|
|
|
- //Send the data via I2C:
|
|
|
- if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS){
|
|
|
- printf("I2C Bus is busy! Retry..\n");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- //start I2C transmission:
|
|
|
- DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_DAC, DL_I2C_CONTROLLER_DIRECTION_TX, 3);
|
|
|
- DL_I2C_fillControllerTXFIFO(I2C_controller_INST, output_buffer, 3);
|
|
|
-
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
-
|
|
|
- if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) {
|
|
|
- printf("I2C Write Error: Failed to write to DAC!\n");
|
|
|
- return false; // Return failure if there was an error
|
|
|
- }
|
|
|
-
|
|
|
- return true;
|
|
|
-}*/
|
|
|
-
|
|
|
-//The device updates all DAC analog output(vout) at the same time
|
|
|
-
|
|
|
-void update_DAC_Output() {
|
|
|
- uint8_t general_call_command = 0x08; // General Call Update Command
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
- DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &general_call_command, 1);
|
|
|
-
|
|
|
- // Start I2C transaction
|
|
|
- DL_I2C_startControllerTransfer(I2C_controller_INST, 0x00, DL_I2C_CONTROLLER_DIRECTION_TX, 1);
|
|
|
-
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
-
|
|
|
- printf("DAC Outputs Updated via General Call Software Update!\n");
|
|
|
-}
|
|
|
-
|
|
|
-/**Function for FAST write command, sending values over I2c to every channel of DAC**/
|
|
|
-bool fastWrite(uint16_t channel_a_value){
|
|
|
-
|
|
|
- /*DAC has a 12 bit resolution that ranges from 0 to 4095.
|
|
|
- 0x00: sets the Power Mode to NORMAL for Channel A
|
|
|
- (channel_a_value >> 8): shifts the value to 8 places right and gives upper 4 bits
|
|
|
- */
|
|
|
-
|
|
|
- uint8_t output_buffer[8];
|
|
|
-
|
|
|
- output_buffer[0]= (0x00)|(channel_a_value >> 8)&0x0F;
|
|
|
- //output_buffer[0] = channel_a_value >> 8;
|
|
|
- output_buffer[1]= channel_a_value & 0xFF;
|
|
|
-
|
|
|
- output_buffer[2]= 0x40; // Power down for the other channels
|
|
|
- output_buffer[3]= 0x00;
|
|
|
-
|
|
|
- output_buffer[4]= 0x40;
|
|
|
- output_buffer[5]= 0x00;
|
|
|
-
|
|
|
- output_buffer[6]= 0x40;
|
|
|
- output_buffer[7]= 0x00;
|
|
|
-
|
|
|
- if (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_ERROR) {
|
|
|
- printf("I2C Write Error: Failed to write to DAC channels for FAST write mode!\n");
|
|
|
- return false; // Return failure if there was an error
|
|
|
- }
|
|
|
-
|
|
|
- // **Wait for I2C Bus to be Free**
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- // **Start I2C Write Transaction**
|
|
|
- DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_DAC, DL_I2C_CONTROLLER_DIRECTION_TX, 8);
|
|
|
-
|
|
|
- // **Load Configuration Byte into TX FIFO**
|
|
|
- DL_I2C_fillControllerTXFIFO(I2C_controller_INST, (uint8_t*)&output_buffer, 8);
|
|
|
-
|
|
|
-
|
|
|
- // **Ensure STOP Condition is Sent**
|
|
|
- while (DL_I2C_getControllerStatus(I2C_controller_INST) & DL_I2C_CONTROLLER_STATUS_BUSY_BUS);
|
|
|
- printf("DAC Fast write Successful!\n");
|
|
|
- update_DAC_Output();
|
|
|
- return true;
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-/*void readRegisters(){
|
|
|
-
|
|
|
- uint8_t data[24];
|
|
|
- uint8_t channel;
|
|
|
- bool isEeprom;
|
|
|
-
|
|
|
- printf("Reading MCP4728 Registers...\n");
|
|
|
-
|
|
|
- // ** Request 24 Bytes from MCP4728 over I2C **
|
|
|
- DL_I2C_startControllerTransfer(I2C_controller_INST, DEF_TARGET_ADDR_DAC, DL_I2C_CONTROLLER_DIRECTION_RX, 24);
|
|
|
-
|
|
|
- for (int i = 0; i < 24; i++) {
|
|
|
- while (DL_I2C_isControllerRXFIFOEmpty(I2C_controller_INST));
|
|
|
- data[i] = DL_I2C_receiveControllerData(I2C_controller_INST);
|
|
|
- }
|
|
|
-
|
|
|
- // ** Process the Received Data (8 Iterations for 4 Channels) **
|
|
|
- for (uint8_t i = 0; i < 8; i++) {
|
|
|
- isEeprom = i % 2; // Even indices: Register, Odd indices: EEPROM
|
|
|
- //Extract channel:
|
|
|
- uint8_t ch= (data[0] & 0x30)>>4;
|
|
|
-
|
|
|
- if (isEeprom) {
|
|
|
- read_eep_[ch].vref = (VREF_SELECTION) ((data[i * 3 + 1] & 0b10000000) >> 7);
|
|
|
- read_eep_[ch].pd = (PWR_DOWN_SELECTION) ((data[i * 3 + 1] & 0b01100000) >> 5);
|
|
|
- read_eep_[ch].gain = (GAIN_SELECTION) ((data[i * 3 + 1] & 0b00010000) >> 4);
|
|
|
- read_eep_[ch].data = (uint16_t) ((data[i * 3 + 1] & 0b00001111) << 8 | data[i * 3 + 2]);
|
|
|
- } else {
|
|
|
- read_reg_[ch].vref = (VREF_SELECTION) ((data[i * 3 + 1] & 0b10000000) >> 7);
|
|
|
- read_reg_[ch].pd = (PWR_DOWN_SELECTION) ((data[i * 3 + 1] & 0b01100000) >> 5);
|
|
|
- read_reg_[ch].gain = (GAIN_SELECTION) ((data[i * 3 + 1] & 0b00010000) >> 4);
|
|
|
- read_reg_[ch].data = (uint16_t) ((data[i * 3 + 1] & 0b00001111) << 8 | data[i * 3 + 2]);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- printf("MCP4728 Registers Read Successfully!\n");
|
|
|
-}
|
|
|
-*/
|
|
|
-
|
|
|
-
|
|
|
-/*
|
|
|
-DAC Function:
|
|
|
--12 bit Voltage Output DAC with Four Buffered outputs.
|
|
|
--Using Internal VREF (2.048V):
|
|
|
- - Output voltage range:
|
|
|
- - 0.000V to 2.048V with Gain setting= 1
|
|
|
- - 0.000V to 4.096V with Gain setting= 2
|
|
|
-- User can select internal reference or external voltage (VDD) for each channel
|
|
|
-- VOUTA: Buffered analog voltage of Channel A.
|
|
|
-- Channel Selection bits: 0x00 for Channel A
|
|
|
-*/
|
|
|
-
|
|
|
-
|
|
|
-/*int16_t read_DAC_Output()
|
|
|
-{
|
|
|
- readRegisters(); //Read current register DAC values
|
|
|
- uint16_t dac_a = read_reg_[DAC_A].data;
|
|
|
- uint16_t dac_b = read_reg_[DAC_B].data;
|
|
|
- uint16_t dac_c = read_reg_[DAC_C].data;
|
|
|
- uint16_t dac_d = read_reg_[DAC_D].data;
|
|
|
-
|
|
|
- printf("DAC Output Digital Values: A=%d, B=%d, C=%d, D=%d\n",
|
|
|
- dac_a, dac_b, dac_c, dac_d);
|
|
|
- return dac_a;
|
|
|
-}
|
|
|
-
|
|
|
-float get_DAC_Output_Voltage(DAC_CH channel){
|
|
|
- if(channel< DAC_A || channel> DAC_D){
|
|
|
- printf("Error: Invalid DAC channel!\n");
|
|
|
- return -1.0;
|
|
|
- }
|
|
|
- uint16_t dac_value = read_reg_[channel].data;
|
|
|
- VREF_SELECTION vref = read_reg_[channel].vref;
|
|
|
- GAIN_SELECTION gain = read_reg_[channel].gain;
|
|
|
-
|
|
|
- //GET correct VREF value:
|
|
|
- float vref_value= (vref==VREF_INTERNAL)? 2.048: 3.3;
|
|
|
- uint8_t gain_factor= (gain==GAIN_X2)? 2: 1;
|
|
|
-
|
|
|
- // Calculate Output Voltage
|
|
|
- float vout = ((float)dac_value / 4095.0) * vref_value * gain_factor;
|
|
|
-
|
|
|
- printf("DAC Channel %d - Digital Value: %d, VOUT: %.3fV\n", channel, dac_value, vout);
|
|
|
- return vout;
|
|
|
-
|
|
|
-}*/
|
|
|
-
|
|
|
-/**Function to call DAC*/
|
|
|
-/*void get_Analog_Output(){
|
|
|
- bool success= fastWrite(2048, 0, 0, 0);
|
|
|
- if(!success){
|
|
|
- printf("Error: DAC Fast Write Failed.\n");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- update_DAC_Output();
|
|
|
- read_DAC_Output();
|
|
|
-
|
|
|
- float vout_a= get_DAC_Output_Voltage(DAC_A);
|
|
|
- float vout_b= get_DAC_Output_Voltage(DAC_B);
|
|
|
- float vout_c= get_DAC_Output_Voltage(DAC_C);
|
|
|
- float vout_d= get_DAC_Output_Voltage(DAC_D);
|
|
|
-
|
|
|
- printf("\nMeasured DAC output Voltages:\n");
|
|
|
- printf("Channel A: %.2f V\n", vout_a);
|
|
|
- printf("Channel B: %.2f V\n", vout_b);
|
|
|
- printf("Channel C: %.2f V\n", vout_c);
|
|
|
- printf("Channel D: %.2f V\n", vout_d);
|
|
|
-}
|
|
|
-*/
|
|
|
-
|
|
|
/*
|
|
|
Function to initialize MCU as target: Pi communicates as the Controller and MCU as the Target
|
|
|
*/
|
|
|
@@ -692,55 +175,6 @@ void I2C_Target_Init(void) {
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-/*
|
|
|
-MAIN function:
|
|
|
-*/
|
|
|
-
|
|
|
-int main(void)
|
|
|
-{
|
|
|
- // **Step 1: Initialize System and I2C**
|
|
|
- SYSCFG_DL_init();
|
|
|
- printf("............System Configuration Enabled...............\n");
|
|
|
-
|
|
|
-
|
|
|
- // **Step 2: Select ADC Channel via Multiplexer**
|
|
|
- printf("Selecting Multiplexer Channel...\n");
|
|
|
- Multiplexer_SelectChannel(ADC_I2C_CHANNEL);
|
|
|
- //I2C_scanBus();
|
|
|
- // **Step 3: Enable I2C Interrupts**
|
|
|
- //NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
|
|
|
- //NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
|
|
|
- I2C_init(&gI2C);
|
|
|
-
|
|
|
- gTxCount = 0;
|
|
|
- gTxLen = REGISTER_SIZE;
|
|
|
- gRxCount = 0;
|
|
|
- gRxLen = REGISTER_SIZE;
|
|
|
-
|
|
|
- // **Step 4: Configure ADC (Example: CH1, 16-bit, Continuous Mode, Gain x1)**
|
|
|
- uint8_t channel= 4;
|
|
|
- uint8_t resolution= 16;
|
|
|
- bool continuous= 1;
|
|
|
- uint8_t gain= 1;
|
|
|
- printf("Configuring ADC...\n");
|
|
|
-
|
|
|
- //**Set Configuration Register for ADC**
|
|
|
- //SetConfiguration(channel, resolution, continuous, gain); // CH1, 16-bit, Continuous mode, Gain x1
|
|
|
-
|
|
|
- while (1)
|
|
|
- {
|
|
|
- // Read ADC Value and DAC values:
|
|
|
- //int16_t adc_value = Read_ADC_Data(resolution);
|
|
|
- //Convert_ADC_To_Voltage(adc_value, resolution, gain);
|
|
|
- //delay_cycles(10000);
|
|
|
- fastWrite(3300);
|
|
|
-
|
|
|
- //Add Delay for Next Conversion**
|
|
|
- delay_cycles(100000);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/*Interrupt for MCU -> ADC
|
|
|
* CASE: DL_I2C_IIDX_CONTROLLER_RX_DONE: ADC Reception Complete
|
|
|
- ADC has finished sending data and it's fully received.
|
|
|
@@ -765,58 +199,57 @@ int main(void)
|
|
|
|
|
|
*/
|
|
|
void I2C_controller_INST_IRQHandler(void)
|
|
|
-{ printf("I2C Interrupt Triggered to ADC!\n");
|
|
|
+{
|
|
|
+ //printf("I2C Interrupt Triggered to ADC!\n");
|
|
|
switch (DL_I2C_getPendingInterrupt(I2C_controller_INST))
|
|
|
- {
|
|
|
- case DL_I2C_IIDX_CONTROLLER_RX_DONE:
|
|
|
- gI2C.rxMsg.len = gI2C.rxMsg.ptr;
|
|
|
- I2C_decodeResponse(&gI2C,&gResponse);
|
|
|
- gI2C.status = I2C_STATUS_RX_COMPLETE;
|
|
|
- printf("I2C RX COMPLETE!\n");
|
|
|
- break;
|
|
|
-
|
|
|
- case DL_I2C_IIDX_CONTROLLER_TX_DONE:
|
|
|
- DL_I2C_disableInterrupt(
|
|
|
- I2C_controller_INST, DL_I2C_INTERRUPT_CONTROLLER_TXFIFO_TRIGGER);
|
|
|
- gI2C.status = I2C_STATUS_TX_COMPLETE;
|
|
|
- printf("I2C TX COMPLETE!\n");
|
|
|
+ { /*START Condition*/
|
|
|
+ case DL_I2C_IIDX_CONTROLLER_START:
|
|
|
+ //gTxADCcount= 0;
|
|
|
+ gRxADCcount= 0;
|
|
|
+ DL_I2C_flushControllerTXFIFO(I2C_controller_INST);
|
|
|
break;
|
|
|
|
|
|
case DL_I2C_IIDX_CONTROLLER_RXFIFO_TRIGGER:
|
|
|
- gI2C.status = I2C_STATUS_RX_INPROGRESS;
|
|
|
+ gI2C.status= I2C_STATUS_RX_INPROGRESS;
|
|
|
/* Store bytes received from target in Rx Msg Buffer */
|
|
|
while (DL_I2C_isControllerRXFIFOEmpty(I2C_controller_INST) != true) {
|
|
|
- if (gI2C.rxMsg.ptr < MAX_BUFFER_SIZE) {
|
|
|
- gI2C.rxMsg.buffer[gI2C.rxMsg.ptr++] =
|
|
|
- DL_I2C_receiveControllerData(I2C_controller_INST);
|
|
|
- if(gI2C.rxMsg.ptr>0){
|
|
|
- //printf("Received Byte[%d]: 0x%02X\n", gI2C.rxMsg.ptr, gI2C.rxMsg.buffer[gI2C.rxMsg.ptr - 1]);
|
|
|
-
|
|
|
- }
|
|
|
+ if (gRxADCcount< gRxADClen) {
|
|
|
+ gRxPacket[gRxADCcount] = DL_I2C_receiveControllerData(I2C_controller_INST);
|
|
|
+ printf("Received Byte[%d]: 0x%02X\n", gRxADCcount, gRxPacket[gRxADCcount]); // Debug print
|
|
|
+ gRxADCcount++;
|
|
|
|
|
|
} else {
|
|
|
- printf("ERROR: RX Buffer Overflow! ptr=%d MAX_BUFFER_SIZE=%d\n", gI2C.rxMsg.ptr, MAX_BUFFER_SIZE);
|
|
|
+ //printf("ERROR: RX Buffer Overflow! ptr=%d MAX_BUFFER_SIZE=%d\n", gI2C.rxMsg.ptr, MAX_BUFFER_SIZE);
|
|
|
/* Ignore and remove from FIFO if the buffer is full */
|
|
|
DL_I2C_receiveControllerData(I2C_controller_INST);
|
|
|
}
|
|
|
+
|
|
|
}
|
|
|
break;
|
|
|
-
|
|
|
+ /*TRANSMIT data to ADC*/
|
|
|
case DL_I2C_IIDX_CONTROLLER_TXFIFO_TRIGGER:
|
|
|
printf("TX FIFO with data!\n");
|
|
|
- gI2C.status = I2C_STATUS_TX_INPROGRESS;
|
|
|
- /* Fill TX FIFO with bytes to send */
|
|
|
- if (gI2C.txMsg.ptr < gI2C.txMsg.len) {
|
|
|
- gI2C.txMsg.ptr += DL_I2C_fillControllerTXFIFO(
|
|
|
- I2C_controller_INST, &gI2C.txMsg.buffer[gI2C.txMsg.ptr], gI2C.txMsg.len - gI2C.txMsg.ptr);
|
|
|
+ gI2C.status= I2C_STATUS_TX_INPROGRESS;
|
|
|
+ if(gTxADCcount<gTxADClen){
|
|
|
+ gTxADCcount+= DL_I2C_fillControllerTXFIFO(I2C_controller_INST, &gTxPacket[gTxADCcount], (gTxADClen-gTxADCcount));
|
|
|
+ } else{
|
|
|
+ /*Prevent overflow and just ignore data*/
|
|
|
+ DL_I2C_fillTargetTXFIFO(I2C_controller_INST, (uint8_t[]){0x00}, 1);
|
|
|
}
|
|
|
break;
|
|
|
-
|
|
|
+ /*STOP condition*/
|
|
|
+ case DL_I2C_IIDX_CONTROLLER_STOP:
|
|
|
+ gTxComplete= true;
|
|
|
+ gRxComplete = true;
|
|
|
+ printf("I2C Stop Detected- RX Complete");
|
|
|
case DL_I2C_IIDX_CONTROLLER_ARBITRATION_LOST:
|
|
|
- printf("Interrupt index for I2C controller Arbitration Lost!\n");
|
|
|
+ //printf("Interrupt index for I2C controller Arbitration Lost!\n");
|
|
|
break;
|
|
|
case DL_I2C_IIDX_CONTROLLER_NACK:
|
|
|
- printf("I2C NACK Received\n");
|
|
|
+ //printf("I2C NACK Received\n");
|
|
|
+ if((gI2C.status== I2C_STATUS_RX_STARTED)|| (gI2C.status= I2C_STATUS_TX_STARTED)){
|
|
|
+ gI2C.status= I2C_STATUS_ERROR;
|
|
|
+ }
|
|
|
break;
|
|
|
default:
|
|
|
break;
|
|
|
@@ -871,7 +304,7 @@ void I2C_target_INST_IRQHandler(void) {
|
|
|
else if (registerAddress < REGISTER_SIZE) {
|
|
|
//Storing the received data from the controller correctly
|
|
|
registers[registerAddress] = DL_I2C_receiveTargetData(I2C_target_INST);
|
|
|
- printf("Stored 0x%02X in Register 0x%02X\n", registers[registerAddress], registerAddress);
|
|
|
+ //printf("Stored 0x%02X in Register 0x%02X\n", registers[registerAddress], registerAddress);
|
|
|
//gRxBuffer[gRxCount++] = DL_I2C_receiveTargetData(I2C_0_INST);
|
|
|
|
|
|
}
|
|
|
@@ -885,33 +318,114 @@ void I2C_target_INST_IRQHandler(void) {
|
|
|
|
|
|
/* TX FIFO trigger (Pi is reading data from MCU) */
|
|
|
case DL_I2C_IIDX_TARGET_TXFIFO_TRIGGER:
|
|
|
+
|
|
|
//printf("transmitting data to Pi...\n");
|
|
|
if(!DL_I2C_isTargetTXFIFOFull(I2C_target_INST)) {
|
|
|
-
|
|
|
- if (registerAddress < REGISTER_SIZE) {
|
|
|
- //DL_I2C_fillTargetTXFIFO(I2C_0_INST, &gTxBuffer[gTxCount], 1);
|
|
|
- // Retrieve stored value from the correct register
|
|
|
- uint8_t value = registers[registerAddress];
|
|
|
- //uint8_t value_test[2] = { 0x01, 0x03 };
|
|
|
- DL_I2C_fillTargetTXFIFO(I2C_target_INST, &value, 1);
|
|
|
- //printf("Sending to 0x%02X: 0x%02X\n", registerAddress, value); // Debugging
|
|
|
- } else {
|
|
|
+ if(registerAddress == 0x01){
|
|
|
+ DL_I2C_fillTargetTXFIFO(I2C_target_INST, battery_status, NUM_BATTERY_SLOT);
|
|
|
+ }
|
|
|
+ else if(registerAddress== 0x02){
|
|
|
+ //DL_I2C_fillTargetTXFIFO(I2C_target_INST, &value , 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ else {
|
|
|
// **Fix: Avoid infinite while loop**
|
|
|
printf("WARNING: TX Buffer Underflow! Sending default value.\n");
|
|
|
DL_I2C_fillTargetTXFIFO(I2C_target_INST, (uint8_t[]){0x00}, 1);
|
|
|
break;
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
/* Arbitration lost or NACK */
|
|
|
case DL_I2C_IIDX_TARGET_ARBITRATION_LOST:
|
|
|
+ printf("Arbitration Lost.\n");
|
|
|
default:
|
|
|
printf("Unknown Interrupt.\n");
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void Reset_I2C_Bus() {
|
|
|
+ printf("I2C Bus is stuck! Resetting...\n");
|
|
|
+
|
|
|
+ // Disable I2C Controller
|
|
|
+ DL_I2C_disableController(I2C_controller_INST);
|
|
|
+ delay_cycles(50000);
|
|
|
+
|
|
|
+ // Re-enable I2C Controller
|
|
|
+ DL_I2C_enableController(I2C_controller_INST);
|
|
|
+ delay_cycles(50000);
|
|
|
+
|
|
|
+ // Check if bus is free now
|
|
|
+ uint32_t status = DL_I2C_getControllerStatus(I2C_controller_INST);
|
|
|
+ printf("I2C Bus Status After Reset: 0x%08X\n", status);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+/*
|
|
|
+MAIN function:
|
|
|
+*/
|
|
|
+
|
|
|
+int main(void)
|
|
|
+{
|
|
|
+ // Initialize System and I2C
|
|
|
+ SYSCFG_DL_init();
|
|
|
+ //Reset_I2C_Bus();
|
|
|
+ //NVIC_EnableIRQ(I2C_target_INST_INT_IRQN);
|
|
|
+ //NVIC_EnableIRQ(I2C_controller_INST_INT_IRQN);
|
|
|
+
|
|
|
+ printf("............System Configuration Enabled...............\n");
|
|
|
+
|
|
|
+ Multiplexer_SelectChannel(I2C_CHANNEL);
|
|
|
+ //I2C_scanBus();
|
|
|
+ I2C_init(&gI2C);
|
|
|
+
|
|
|
+ // *Configure ADC*
|
|
|
+ ADC_PARAMS adc_params={
|
|
|
+ .channel= 1,
|
|
|
+ .resolution= 12,
|
|
|
+ .continuous= 1,
|
|
|
+ .gain= 1
|
|
|
+
|
|
|
+ };
|
|
|
+
|
|
|
+ printf("Configuring ADC....\n");
|
|
|
+ //**Set Configuration Register for ADC**
|
|
|
+ ADC_SetConfigurationBytes(adc_params);
|
|
|
+ uint16_t channel_a_value= 3300; // in mVolts
|
|
|
+ while (1)
|
|
|
+ {
|
|
|
+ int16_t raw_adc_value= ADC_ReadData(adc_params);
|
|
|
+ ADC_ConvertToVoltage(raw_adc_value, adc_params);
|
|
|
+ delay_cycles(5000);
|
|
|
+ DAC_fastWrite(channel_a_value);
|
|
|
+ delay_cycles(100000);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //Read_ADC_Data(resolution);
|
|
|
+ //for(uint8_t slot=0; slot<NUM_BATTERY_SLOT; slot++){
|
|
|
+ // Read ADC Value and DAC values:
|
|
|
+ //int16_t adc_value = Read_ADC_Data(resolution);
|
|
|
+ //Read_ADC_Data(resolution);
|
|
|
+ //float measured_adc_volts= Convert_ADC_To_Voltage(adc_value, resolution, gain);
|
|
|
+ //if(measured_adc_volts> BATT_THRESHOLD){
|
|
|
+ //battery_status[slot]= 0x02;
|
|
|
+ //}else{
|
|
|
+ // battery_status[slot]= 0x01;
|
|
|
+ //}
|
|
|
+ // Debugging Output
|
|
|
+ //printf("Battery Slot %d - Voltage: %.2fV, Status: 0x%02X\n", slot, measured_adc_volts, battery_status[slot]);
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
|