Other Parts Discussed in Thread: BQSTUDIO
Tool/software:
Good afternoon,
I'm an inexperienced programmer so I'm sorry if the question is somewhat inappropriate.
I am trying to change a value in the DATA FLASH MEMORY of my bq35100. To do this, I first verify that the device is in full access mode. Then I read the value of ccgain and it gives me a result of 17276.
After trying to change the value to these values: 0x1234 and 0x5678. After that I read the ccgain values again but they still give 17276. What am I doing wrong? Am I missing something in between? I attach the code I use:
FUNCTIONS:
// Function to read a 16-bit register
uint16_t read16bitRegister(uint8_t reg_addr, unsigned char numBytesReceived) {
uint16_t data;
TWI_BQRead(reg_addr, numBytesReceived); // Read 2 bytes from the specified register
data = (twi_data_buffer[1] << 8) | twi_data_buffer[0]; // Combine the two bytes read in little-endian format
return data;
}
// Function to write a 16-bit register in little-endian format
void write16bitRegister(uint8_t reg_addr, uint16_t data) {
uint8_t low_byte = data & 0xFF;
uint8_t high_byte = (data >> 8) & 0xFF;
TWI_BQWrite(reg_addr, low_byte, high_byte); // Write the two bytes in little-endian format
_delay_ms(10); // Add a small delay to ensure the write completes
}
uint16_t readCCGain() {
uint16_t cc_gain;
// Step 1: Write the register address to ManufacturerAccessControl
write16bitRegister(MANUFACTURER_ACCESS_REG, 0x4000); // Address of CC Gain in DataFlash
_delay_ms(10); // Pause to process
// Step 2: Start reading from MACData (0x40)
TWI_BQRead(0x40, 2); // Read 2 bytes from MACData address (0x40)
// Step 3: Combine the two bytes read in little-endian format
cc_gain = (twi_data_buffer[1] << 8) | twi_data_buffer[0];
return cc_gain; // Return the CC Gain value
}
void writeCCGain(uint16_t new_value) {
uint8_t checksum;
// Step 1: Write the register address to ManufacturerAccessControl
write16bitRegister(MANUFACTURER_ACCESS_REG, 0x4000); // Address of CC Gain in DataFlash
_delay_ms(10); // Pause to process
// Step 2: Write the new value to MACData (0x40)
TWI_BQWrite(0x40, new_value & 0xFF, (new_value >> 8) & 0xFF); // Write the value in little-endian format
// Step 3: Calculate the checksum
checksum = 0x00 + 0x40 + (new_value & 0xFF) + ((new_value >> 8) & 0xFF); // Add the address and data values
checksum = ~checksum + 1; // 2's complement
// Step 4: Write the checksum and length
TWI_BQWrite(0x60, checksum, 0x02); // Write the checksum and length (2 bytes)
_delay_ms(10); // Pause to ensure the write completes
}
void displayCCGainOnConsole() {
uint16_t cc_gain;
char buffer[10]; // Buffer to store the value converted to string
// Read the CC Gain value
cc_gain = readCCGain(); // Call the function that reads CC Gain
// Convert the CC Gain value to a string (decimal)
itoa(cc_gain, buffer, 10); // Convert the value to a decimal string (base 10)
// Send the value to the console
send_AT_command("CC Gain value: ");
send_AT_command(buffer); // Send the converted value as a string
}
void verifyDeviceStatus() {
uint16_t control_status;
char buffer[10];
// Read the value from the Control Status register
control_status = read16bitRegister(CONTROL_STATUS_REG, 2); // Read 2 bytes from the Control Status register
// Extract SEC1 and SEC0 bits (bits 14 and 13)
uint8_t sec_bits = (control_status >> 13) & 0x03; // Get SEC1 and SEC0 bits
// Display the current mode on the console
if (sec_bits == 0x01) {
send_AT_command("Mode: Full Access");
} else if (sec_bits == 0x02) {
send_AT_command("Mode: Unsealed");
} else if (sec_bits == 0x03) {
send_AT_command("Mode: Sealed");
} else {
send_AT_command("Mode: Reserved or unknown");
}
// Display the Control Status value on the console (optional)
itoa(control_status, buffer, 16);
send_AT_command("Control Status value: ");
send_AT_command(buffer);
}
void unlockDevice() {
verifyDeviceStatus(); // Verify the current state before attempting to unlock
uint16_t control_status = read16bitRegister(CONTROL_STATUS_REG, 2); // Read the current state
uint8_t sec_bits = (control_status >> 13) & 0x03; // Get SEC1 and SEC0 bits
// If the device is in Sealed mode (11), send the Unseal command
if (sec_bits == 0x03) {
send_AT_command("Attempting to unlock the device...");
// Step 1: Send the Unseal command (typically 0x8000)
write16bitRegister(MANUFACTURER_ACCESS_REG, 0x8000); // Send Unseal command
_delay_ms(1000); // Pause to process
// Step 2: Send the Full Access command if necessary (0xFFFF)
write16bitRegister(MANUFACTURER_ACCESS_REG, 0xFFFF); // Send Full Access command
_delay_ms(1000); // Pause to process
send_AT_command("Unlock command sent. Verifying status...");
// Verify the status after attempting to unlock
verifyDeviceStatus(); // Display the new state on the console
} else {
send_AT_command("The device is already unlocked.");
}
}
void writeToDataFlash(uint16_t address, uint16_t value1, uint16_t value2) {
uint8_t checksum;
uint8_t macData[4];
uint8_t sum = 0;
// Write the address to ManufacturerAccessControl (0x3E, 0x3F) in little-endian
write16bitRegister(MANUFACTURER_ACCESS_REG, address); // Write address 0x4000 to ManufacturerAccessControl
_delay_ms(500); // Pause to process
// Write the data to MACData (0x40–0x43) in big-endian
macData[0] = (value1 >> 8) & 0xFF; // High byte of value1
macData[1] = value1 & 0xFF; // Low byte of value1
macData[2] = (value2 >> 8) & 0xFF; // High byte of value2
macData[3] = value2 & 0xFF; // Low byte of value2
// Write the 4 bytes of data to MACData
TWI_BQWrite(0x40, macData[0], macData[1]); // Write the first two bytes (0x40-0x41)
TWI_BQWrite(0x42, macData[2], macData[3]); // Write the second two bytes (0x42-0x43)
_delay_ms(500); // Pause to process
// Calculate the checksum: complement of the sum of ManufacturerAccessControl and MACData
sum += (address & 0xFF); // Low byte of the address
sum += (address >> 8) & 0xFF; // High byte of the address
sum += macData[0]; // Sum of the data
sum += macData[1];
sum += macData[2];
sum += macData[3];
checksum = ~sum + 1; // 2's complement
// Write the checksum to MACDataSum (0x60)
TWI_BQWrite(0x60, checksum, 0x00); // Write the checksum
_delay_ms(500); // Pause to process
// Write the data length to MACDataLen (0x61)
TWI_BQWrite(0x61, 0x08, 0x00); // Total length: 4 + length of MACData
_delay_ms(500); // Pause to process
}
void changeCCGainValue() {
uint16_t new_value1 = 0x1234; // First value to write (0x1234 in hexadecimal)
uint16_t new_value2 = 0x5678; // Second value to write (0x5678 in hexadecimal)
unlockDevice(); // Ensure the device is unlocked
_delay_ms(1000);
// Call the function to write to DataFlash at address 0x4000
writeToDataFlash(0x4000, new_value1, new_value2);
// Send a message to the console to confirm
send_AT_command("New values written to CC Gain: 0x1234 and 0x5678");
}
MAIN:
_delay_ms(3000);
send_AT_command("Reading CC Gain value...");
displayCCGainOnConsole();
_delay_ms(1000);
send_AT_command("Changing CC Gain values...");
changeCCGainValue();
_delay_ms(3000);
Thank you. All the best