-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* implemented i2cdetect function. * Fixed spacing and added comments. * Separate i2c_utility functions files. * Fixed Displaying For i2cdetect and reverted back to a single file. * Created implementation of byte-read i2cdump function. * Implemented i2cdump word mode. * Lowered the timeout length to 50ms. * Created print function to serial monitor.
- Loading branch information
1 parent
78ae0e0
commit 0ff91be
Showing
2 changed files
with
208 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#ifndef I2C_UTILITY_H | ||
#define I2C_UTILITY_H | ||
|
||
#include "stm32f4xx_hal.h" | ||
#include "serial_monitor.h" | ||
#include <stdint.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
|
||
#define HEX_LABELS "\t 0 1 2 3 4 5 6 7 8 9 a b c d e f\n" | ||
#define SPACING " " // Spacing in between each printed address | ||
#define MAX_TRIALS 3 // Max attempts to probe I2C device | ||
#define TIMEOUT 50 // Max time until function skips | ||
#define HEX 16 // hexadecimal for utoa function | ||
#define BUF_ROWS 8 // Number of rows in the buffer | ||
#define ROW_BYTES 128 // Number of bytes per row | ||
|
||
/** | ||
* @brief Probes all i2c addresses to check if devices are ready. | ||
* | ||
* @param hi2c address of the i2c bus | ||
* @param buffer array to input the result in | ||
* @param mode | ||
* @param start | ||
* @param end | ||
* | ||
* @return int | ||
*/ | ||
int i2cdetect(I2C_HandleTypeDef *hi2c, char **buffer, int mode, uint8_t start, uint8_t end); | ||
|
||
/** | ||
* @brief Reads and dumps register data at a given register address and i2c bus. | ||
* | ||
* @param hi2c address of the i2c bus | ||
* @param devAddress specific device address in the i2c bus to dump. | ||
* @param buffer array to input the result in | ||
* @param mode reading mode (default: byte) | ||
* @param start lower range of addresses to dump from | ||
* @param end higher range of addresses to dump from | ||
*/ | ||
int i2cdump(I2C_HandleTypeDef *hi2c, uint16_t devAddress, char **buffer, char mode, uint8_t start, uint8_t end); | ||
|
||
/** | ||
* @brief Prints the given 2D Array to serial monitor | ||
* | ||
* @param buffer | ||
*/ | ||
void printResult(char **buffer); | ||
|
||
#endif // I2C_UTILITY_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
#include "i2c_utility.h" | ||
|
||
char *hex_labels[] = {"00:", "10:", "20:", "30:", "40:", "50:", | ||
"60:", "70:", "80:", "90:", "a0:", "b0:", "c0:", "d0:", "e0:", "f0:"}; | ||
|
||
/** | ||
* TODO: Implement modes for I2C Communication. | ||
* TODO: Implement for flags. | ||
* TODO: Check for error handling | ||
*/ | ||
int i2cdetect(I2C_HandleTypeDef *hi2c, char **buffer, int mode, uint8_t start, uint8_t end) { | ||
// Initialize the buffer and local variables | ||
HAL_StatusTypeDef ret; | ||
uint8_t row = 1; | ||
char status[sizeof(uint8_t) * 8 + 1]; | ||
|
||
// Add to the appropriate buffer | ||
buffer[0] = HEX_LABELS; //add labels to the first row of the buffer | ||
|
||
// Loop through each device address from the start to end | ||
for(unsigned int i = 0x00U; i <= 0x70U; i+=0x10U) { | ||
strcat(buffer[row], hex_labels[row - 1]); | ||
for(unsigned int j = 0x00U; j < 0x10U; j += 0x01U) { | ||
uint8_t devAddr = i + j; | ||
// out of range reading | ||
if(devAddr < start || devAddr > end) { | ||
strcpy(status, SPACING); | ||
} | ||
// in range | ||
else { | ||
// Use HAL_I2C_IsDeviceReady | ||
ret = HAL_I2C_IsDeviceReady(hi2c, (devAddr << 1), MAX_TRIALS, TIMEOUT); | ||
|
||
// Device status case | ||
switch (ret) { | ||
case HAL_BUSY: | ||
strcpy(status, "UU"); // the bus is considered busy | ||
break; | ||
case HAL_OK: | ||
utoa(devAddr, status, HEX); // reads the hexadecimal address and turns it into a string | ||
break; | ||
case HAL_ERROR: | ||
case HAL_TIMEOUT: | ||
default: | ||
strcpy(status, "--"); // no response from device or not found | ||
break; | ||
} | ||
} | ||
|
||
// Add status to the buffer | ||
strcat(buffer[row], SPACING); // spacing for string | ||
strcat(buffer[row], status); // actual status | ||
|
||
// clear char array | ||
memset(status, 0, strlen(status)); | ||
} | ||
// table update | ||
strcat(buffer[row], "\n"); | ||
row++; | ||
} | ||
|
||
// Return normal status | ||
return 0; | ||
} | ||
|
||
/** | ||
* TODO: Implement different reading modes | ||
* HAL_I2C_Master_Receive() - requests data from slave device. (BLOCKING) | ||
* HAL_I2C_Mem_Read() - requests data from slave device from a specific memory address. (NON-BLOCKING) | ||
*/ | ||
int i2cdump(I2C_HandleTypeDef *hi2c, uint16_t devAddress, char **buffer, char mode, uint8_t start, uint8_t end) { | ||
// Prepare the buffer | ||
int row = 0; | ||
|
||
// need to read from the given address of a I2C Bus. | ||
switch(mode) { | ||
case 'w': // A word (4 bytes or 32-bit) | ||
buffer[row] = "\t\t0 4 8 b"; | ||
row ++; | ||
|
||
uint8_t data1 = 0; | ||
for(unsigned int i = 0x00U; i <= 0xf0U; i += 0x10U) { | ||
buffer[row] = hex_labels[row - 1]; | ||
char data_str[sizeof(char) * 4 + 1]; | ||
|
||
for(unsigned int j = 0x00U; j <= 0x0fU; j += 0x04U) { | ||
uint16_t reg = i + j; | ||
// read memory address | ||
if (HAL_I2C_Mem_Read(hi2c, (devAddress << 1), reg, I2C_MEMADD_SIZE_8BIT, &data1, 4, HAL_MAX_DELAY) != HAL_OK) { | ||
// error | ||
return HAL_ERROR; | ||
} | ||
|
||
// convert data into char text | ||
utoa(data1, data_str, HEX); | ||
|
||
// display the value from the memory address | ||
strcat(buffer[row], SPACING); | ||
strcat(buffer[row], data_str); | ||
|
||
// reset the string array | ||
memset(data_str, 0, strlen(data_str)); | ||
} | ||
strcat(buffer[row], "\n"); | ||
row++; | ||
} | ||
break; | ||
case 's': // A SMBus Block | ||
break; | ||
case 'i': // I2C Block | ||
break; | ||
case 'b': // Byte sized (default) | ||
default: | ||
// Add the labels to the first row | ||
buffer[row] = HEX_LABELS; | ||
row ++; | ||
|
||
uint8_t data = 0; | ||
for (unsigned int i = 0x00U; i <= 0xf0U; i += 0x10U) { | ||
// add the vertical labels | ||
buffer[row] = hex_labels[row - 1]; | ||
char data_str[sizeof(char) * 2 + 1]; | ||
|
||
for(unsigned int j = 0x00U; j <= 0x0fU; j++) { | ||
uint16_t reg = i + j; // get the memory address | ||
// read memory address | ||
if (HAL_I2C_Mem_Read(hi2c, (devAddress << 1), reg, I2C_MEMADD_SIZE_8BIT, &data, 1, HAL_MAX_DELAY) != HAL_OK) { | ||
// error | ||
return HAL_ERROR; | ||
} | ||
|
||
// Convert data buffer into the char buffer | ||
utoa(data, data_str, HEX); | ||
|
||
// display the value from the memory address | ||
strcat(buffer[row], SPACING); | ||
strcat(buffer[row], data_str); | ||
|
||
// reset the string array | ||
memset(data_str, 0, strlen(data_str)); | ||
} | ||
strcat(buffer[row], "\n"); | ||
row++; | ||
} | ||
break; | ||
} | ||
// nominal return | ||
return HAL_OK; | ||
} | ||
|
||
/** | ||
* @warning serial_print max size is 128 bytes. | ||
*/ | ||
void printResult(char **buffer, int len) { | ||
for(int i = 0; i < len; i++) { | ||
serial_print(buffer[i]); | ||
} | ||
} |