27 #include <libopencm3/stm32/i2c.h> 41 #define BUSVOODOO_I2C I2C2 45 static enum busvoodoo_i2c_setting_t { 46 BUSVOODOO_I2C_SETTING_NONE,
47 BUSVOODOO_I2C_SETTING_SPEED,
48 BUSVOODOO_I2C_SETTING_ADDRESSBITS,
49 BUSVOODOO_I2C_SETTING_PULLUP,
50 BUSVOODOO_I2C_SETTING_DONE,
66 bool complete =
false;
71 case BUSVOODOO_I2C_SETTING_NONE:
76 case BUSVOODOO_I2C_SETTING_SPEED:
77 if (NULL==line || 0==strlen(line)) {
80 uint32_t speed = atoi(line);
81 if (speed>0 && speed<=400) {
91 case BUSVOODOO_I2C_SETTING_ADDRESSBITS:
92 if (NULL==line || 0==strlen(line)) {
95 uint8_t addressbits = atoi(line);
96 if (7==addressbits || 10==addressbits) {
102 printf(
"1) open-drain, with embedded pull-up resistors (2kO)\n");
103 printf(
"2) open-drain, with external pull-up resistors\n");
108 case BUSVOODOO_I2C_SETTING_PULLUP:
109 if (NULL==line || 0==strlen(line)) {
111 }
else if (1==strlen(line)) {
112 uint8_t drive = atoi(line);
113 if (1==drive || 2==drive) {
122 printf(
"use LV to set pull-up voltage\n");
128 const char* pinout_io[10] = {
"GND",
"5V",
"3V3",
"LV",
"SDA",
"SCL", NULL, NULL};
137 case BUSVOODOO_I2C_SETTING_DONE:
165 printf(
"slave not selected");
168 printf(
"slave not ready");
171 printf(
"not in receive mode");
184 printf(
"write 0x%02x: ", data);
194 printf(
"slave not selected");
197 printf(
"slave not ready");
200 printf(
"not in transmit mode");
220 printf(
" to %s: ", write ?
"write" :
"read");
230 printf(
"can't become master");
233 printf(
"not in receive mode");
236 printf(
"not in transmit mode");
252 uint32_t length = strlen(action);
253 if (NULL==action || 0==length) {
257 if (1==length &&
'r'==action[0]) {
261 for (uint32_t i=0; i<repetition; i++) {
264 }
else if (1==length &&
'['==action[0]) {
268 printf(
"send start condition: ");
269 for (uint32_t i=0; i<repetition; i++) {
274 }
else if (1==length &&
']'==action[0]) {
278 printf(
"send stop condition: ");
279 for (uint32_t i=0; i<repetition; i++) {
284 }
else if (1==length &&
'u'==action[0]) {
288 printf(
"wait for %u us\n", repetition);
290 }
else if (1==length &&
'm'==action[0]) {
294 printf(
"wait for %u ms\n", repetition);
296 }
else if (
'0'==action[0]) {
301 for (uint32_t i=0; i<repetition; i++) {
304 }
else if (
'x'==action[1] ||
'b'==action[1]) {
306 }
else if (action[1]>=
'0' && action[1]<=
'9') {
308 }
else if (
'r'==action[1] && 2==length) {
310 }
else if (
'w'==action[1] && 2==length) {
315 }
else if (
'x'==action[0] && length>1) {
316 for (uint32_t i=1; i<length; i++) {
317 if (!((action[i]>=
'0' && action[i]<=
'9') || (action[i]>=
'a' && action[i]<=
'f') || (action[i]>=
'A' && action[i]<=
'F') || (
'r'==action[i] && i==length-1) || (
'w'==action[i] && i==length-1))) {
324 uint32_t value = strtol(&action[1], NULL, 16);
325 for (uint32_t i=0; i<repetition; i++) {
326 if (
'r'==action[length-1]) {
328 }
else if (
'w'==action[length-1]) {
334 }
else if (
'b'==action[0] && length>1) {
335 for (uint32_t i=1; i<length; i++) {
336 if (!(
'0'==action[i] ||
'1'==action[i] || (
'r'==action[i] && i==length-1) || (
'w'==action[i] && i==length-1))) {
343 uint32_t value = strtol(&action[1], NULL, 2);
344 for (uint32_t i=0; i<repetition; i++) {
345 if (
'r'==action[length-1]) {
347 }
else if (
'w'==action[length-1]) {
353 }
else if (action[0]>=
'1' && action[0]<=
'9') {
354 for (uint32_t i=1; i<length; i++) {
355 if (!((action[i]>=
'0' && action[i]<=
'9') || (
'w'==action[i] && i==length-1))) {
362 uint32_t value = strtol(&action[0], NULL, 10);
363 for (uint32_t i=0; i<repetition; i++) {
364 if (
'r'==action[length-1]) {
366 }
else if (
'w'==action[length-1]) {
372 }
else if (length>=2 && (
'"'==action[0] ||
'\''==action[0]) && (action[length-1]==action[0])) {
376 for (uint32_t r=0; r<repetition; r++) {
377 for (uint32_t i=1; i<length-1; i++) {
394 if (NULL==argument || 0==strlen(argument)) {
395 printf(
"available actions (separated by space or ,):\n");
396 printf(
"[/]\tsend start/stop conditions\n");
397 printf(
"0x0r\tselect slave with I2C address to read\n");
398 printf(
"0x0w\tselect slave with I2C address to write\n");
399 printf(
"0\twrite decimal value\n");
400 printf(
"0x0\twrite hexadecimal value\n");
401 printf(
"0b0\twrite binary value\n");
402 printf(
"\"a\"/'a'\twrite ASCII characters\n");
403 printf(
"r\tread value\n");
404 printf(
"u/m\twait 1 us/ms\n");
405 printf(
":n\trepeat action n times\n");
409 char* copy = calloc(strlen(argument)+1,
sizeof(
char));
413 strncpy(copy, argument, strlen(argument)+1);
416 printf(
"malformed action(s)\n");
430 printf(
"SCL or/and SDA are low. The signals need to be pulled up\n");
432 printf(
"set pull-up voltage with LV\n");
439 printf(
"scanning for I2C slaves\n");
440 int16_t i2c_slaves = 0;
452 printf(
"start condition failed\n");
458 printf(
"start condition failed\n");
470 if (-1==i2c_slaves) {
472 }
else if (-2==i2c_slaves) {
479 printf(
"stop condition failed\n");
490 printf(
"%u slave(s) found\n", i2c_slaves);
499 "perform protocol actions",
507 "scan for slave devices",
516 "Inter-Integrated Circuit",
library to communicate using I2C as master (API)
enum i2c_master_rc i2c_master_stop(uint32_t i2c)
sent stop condition
#define BUSVOODOO_LED_PULSE
recommended duration in ms for pulsing LEDs to show activity
BusVoodoo global definitions and methods (API)
struct busvoodoo_mode_t busvoodoo_i2c_mode
I2C mode interface definition.
enum i2c_master_rc i2c_master_select_slave(uint32_t i2c, uint16_t slave, bool address_10bit, bool write)
select I2C slave device
static void busvoodoo_i2c_write(uint8_t data)
write to I2C
void busvoodoo_oled_text_pinout(const char *pins[10], bool io_connector)
draw pin names on bottom (blue) part in display buffer
void busvoodoo_led_red_pulse(uint16_t ms)
pulse red LED for short duration
enum i2c_master_rc i2c_master_read(uint32_t i2c, uint8_t *data, size_t data_size)
read data over I2C
void i2c_master_reset(uint32_t i2c)
reset I2C peripheral, fixing any locked state
void led_off(void)
switch off board LED
enum i2c_master_rc i2c_master_start(uint32_t i2c)
send start condition
void busvoodoo_oled_update(void)
update OLED display RAM with current display buffer
uint16_t busvoodoo_i2c_speed
I2C speed (in kHz)
global definitions and methods (API)
static void busvoodoo_i2c_exit(void)
exit I2C mode
void busvoodoo_led_blue_pulse(uint16_t ms)
pulse blue LED for short duration
void sleep_us(uint32_t duration)
go to sleep for some microseconds
static void busvoodoo_i2c_select(uint16_t slave, bool write)
select I2C slave
enum i2c_master_rc i2c_master_write(uint32_t i2c, const uint8_t *data, size_t data_size)
write data over I2C
a start or stop condition is already in progress
#define BUSVOODOO_I2C
I2C peripheral.
bool busvoodoo_i2c_embedded_pullup
if embedded or external pull-up resistors are use
void i2c_master_setup(uint32_t i2c, uint16_t frequency)
setup I2C peripheral
void i2c_master_release(uint32_t i2c)
release I2C peripheral
const char * busvoodoo_global_pinout_io[10]
I/O connector pinout.
static bool busvoodoo_i2c_setup(char **prefix, const char *line)
setup I2C mode
char busvoodoo_global_string[64]
shared string buffer, i.e.
static const struct menu_command_t busvoodoo_i2c_commands[]
I2C menu commands.
size_t snprintf(char *str, size_t size, const char *format,...)
print format string on string or user output
bool busvoodoo_global_actions(char *actions, bool perform, bool(*action_handler)(const char *action, uint32_t repetition, bool perform))
parse and perform actions
static bool busvoodoo_i2c_action(const char *action, uint32_t repetition, bool perform)
perform I2C action
void sleep_ms(uint32_t duration)
go to sleep for some milliseconds
size_t printf(const char *format,...)
print format string on user output
slave is not read (previous operations has been nacked)
printing utilities to replace the large printf from the standard library (API)
void busvoodoo_oled_text_left(char *text)
draw mode text on top (yellow) left side in display buffer
float busvoodoo_embedded_pullup(bool on)
enable embedded pull-up resistors
static void busvoodoo_i2c_read(void)
read from I2C
#define LENGTH(x)
get the length of an array
bool i2c_master_check_signals(uint32_t i2c)
check if SDA and SCL signals are high
library to show BusVoodoo mode information on SSD1306 OLED display: name, activity, pinout (API)
static enum busvoodoo_i2c_setting_t busvoodoo_i2c_setting
current mode setup stage
BusVoodoo mode interface.
static void busvoodoo_i2c_command_actions(void *argument)
command to perform actions
uint8_t busvoodoo_i2c_addressbits
I2C address bits (7 or 10)
static void busvoodoo_i2c_command_scan(void *argument)
command to scan for slave devices