27 #include <libopencm3/stm32/gpio.h> 28 #include <libopencm3/stm32/rcc.h> 29 #include <libopencm3/stm32/spi.h> 42 #define BUSVOODOO_SPI_ID 2 46 static enum busvoodoo_spi_setting_t { 47 BUSVOODOO_SPI_SETTING_NONE,
48 BUSVOODOO_SPI_SETTING_DUPLEX,
49 BUSVOODOO_SPI_SETTING_FREQUENCY,
50 BUSVOODOO_SPI_SETTING_DATABITS,
51 BUSVOODOO_SPI_SETTING_BITORDER,
52 BUSVOODOO_SPI_SETTING_MODE,
53 BUSVOODOO_SPI_SETTING_DRIVE,
54 BUSVOODOO_SPI_SETTING_DONE,
78 bool complete =
false;
83 case BUSVOODOO_SPI_SETTING_NONE:
85 printf(
"1) full-duplex\n");
86 printf(
"2) bidirectional\n");
90 case BUSVOODOO_SPI_SETTING_DUPLEX:
91 if (NULL==line || 0==strlen(line)) {
93 }
else if (1==strlen(line)) {
94 uint8_t duplex = atoi(line);
95 if (1==duplex || 2==duplex) {
102 for (uint8_t div=0; div<8; div++) {
103 printf(
"%u) %u kHz\n", div+1, 36000/(2<<div));
109 case BUSVOODOO_SPI_SETTING_FREQUENCY:
110 if (NULL==line || 0==strlen(line)) {
112 }
else if (1==strlen(line)) {
113 uint8_t baudrate = atoi(line);
114 if (baudrate>0 && baudrate<=9) {
124 case BUSVOODOO_SPI_SETTING_DATABITS:
125 if (NULL==line || 0==strlen(line)) {
127 }
else if (1==strlen(line) || 2==strlen(line)) {
128 uint8_t databits = atoi(line);
129 if (8==databits || 16==databits) {
135 printf(
"1) most significant bit first\n");
136 printf(
"2) least significant bit first\n");
141 case BUSVOODOO_SPI_SETTING_BITORDER:
142 if (NULL==line || 0==strlen(line)) {
144 }
else if (1==strlen(line)) {
145 uint8_t bitorder = atoi(line);
146 if (1==bitorder || 2==bitorder) {
152 printf(
"1) mode 0 (clock polarity: idle low, clock phase: sample data on rising edge)\n");
153 printf(
"2) mode 1 (clock polarity: idle low, clock phase: sample data on falling edge)\n");
154 printf(
"3) mode 2 (clock polarity: idle high, clock phase: sample data on falling edge)\n");
155 printf(
"4) mode 3 (clock polarity: idle high, clock phase: sample data on rising edge)\n");
160 case BUSVOODOO_SPI_SETTING_MODE:
161 if (NULL==line || 0==strlen(line)) {
163 }
else if (1==strlen(line)) {
164 uint8_t mode = atoi(line);
165 if (mode>=1 && mode<=4) {
171 printf(
"1) push-pull (3.3V)\n");
172 printf(
"2) open-drain, with embedded pull-up resistors (2kO)\n");
173 printf(
"3) open-drain, with external pull-up resistors\n");
178 case BUSVOODOO_SPI_SETTING_DRIVE:
179 if (NULL==line || 0==strlen(line)) {
181 }
else if (1==strlen(line)) {
182 uint8_t drive = atoi(line);
183 if (1==drive || 2==drive || 3==drive) {
190 rcc_periph_clock_enable(RCC_AFIO);
241 printf(
"use LV to set pull-up voltage\n");
247 const char* pinout_io[10] = {
"GND",
"5V",
"3V3",
"LV", NULL, NULL,
"MISO",
"SCK",
"MOSI",
"SS"};
250 pinout_io[8] =
"MOSIMISO";
273 printf(
"write: 0x%02x\n", (uint8_t)value);
275 printf(
"write: 0x%04x\n", value);
285 printf(
"read: 0x%02x\n", (uint8_t)value);
287 printf(
"read: 0x%04x\n", value);
306 printf(
"read: 0x%02x\n", (uint8_t)value);
308 printf(
"read: 0x%04x\n", value);
340 uint32_t length = strlen(action);
341 if (NULL==action || 0==length) {
345 if (1==length &&
'r'==action[0]) {
349 for (uint32_t i=0; i<repetition; i++) {
352 }
else if (1==length &&
'['==action[0]) {
359 }
else if (1==length &&
']'==action[0]) {
363 printf(
"de-select slave\n");
366 }
else if (1==length &&
'u'==action[0]) {
370 printf(
"wait for %u us\n", repetition);
372 }
else if (1==length &&
'm'==action[0]) {
376 printf(
"wait for %u ms\n", repetition);
378 }
else if (
'0'==action[0]) {
383 for (uint32_t i=0; i<repetition; i++) {
386 }
else if (
'x'==action[1] ||
'b'==action[1]) {
388 }
else if (action[1]>=
'0' && action[1]<=
'9') {
393 }
else if (
'x'==action[0] && length>1) {
394 for (uint32_t i=1; i<length; i++) {
395 if (!((action[i]>=
'0' && action[i]<=
'9') || (action[i]>=
'a' && action[i]<=
'f') || (action[i]>=
'A' && action[i]<=
'F'))) {
402 uint32_t value = strtol(&action[1], NULL, 16);
403 for (uint32_t i=0; i<repetition; i++) {
406 }
else if (
'b'==action[0] && length>1) {
407 for (uint32_t i=1; i<length; i++) {
408 if (action[i]<
'0' || action[i]>
'1') {
415 uint32_t value = strtol(&action[1], NULL, 2);
416 for (uint32_t i=0; i<repetition; i++) {
419 }
else if (action[0]>=
'1' && action[0]<=
'9') {
420 for (uint32_t i=1; i<length; i++) {
421 if (action[i]<
'0' || action[i]>
'9') {
428 uint32_t value = strtol(&action[0], NULL, 10);
429 for (uint32_t i=0; i<repetition; i++) {
432 }
else if (length>=2 && (
'"'==action[0] ||
'\''==action[0]) && (action[length-1]==action[0])) {
436 for (uint32_t r=0; r<repetition; r++) {
437 for (uint32_t i=1; i<length-1; i++) {
454 if (NULL==argument || 0==strlen(argument)) {
455 printf(
"available actions (separated by space or ,):\n");
456 printf(
"[/]\tselect/deselect slave\n");
457 printf(
"0\twrite decimal value\n");
458 printf(
"0x0\twrite hexadecimal value\n");
459 printf(
"0b0\twrite binary value\n");
460 printf(
"\"a\"/'a'\twrite ASCII characters\n");
461 printf(
"r\tread value\n");
462 printf(
"u/m\twait 1 us/ms\n");
463 printf(
":n\trepeat action n times\n");
467 char* copy = calloc(strlen(argument)+1,
sizeof(
char));
471 strncpy(copy, argument, strlen(argument)+1);
474 printf(
"malformed action(s)\n");
486 "perform protocol actions",
495 "Serial Peripheral Interface",
#define BUSVOODOO_SPI_ID
SPI peripheral.
#define SPI_MOSI_PORT(x)
get SPI port for MOSI signal based on SPI identifier
#define BUSVOODOO_LED_PULSE
recommended duration in ms for pulsing LEDs to show activity
BusVoodoo global definitions and methods (API)
static bool busvoodoo_spi_setup(char **prefix, const char *line)
setup SPI mode
static void busvoodoo_spi_command_actions(void *argument)
command to perform actions
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
static bool busvoodoo_spi_drive
pin drive mode (true = push-pull, false = open-drain)
static enum busvoodoo_spi_setting_t busvoodoo_spi_setting
current mode setup stage
#define SPI_NSS_PORT(x)
get SPI port for NSS signal based on SPI identifier
void led_off(void)
switch off board LED
void busvoodoo_oled_update(void)
update OLED display RAM with current display buffer
#define SPI_MOSI_PIN(x)
get SPI pin for MOSI signal based on SPI identifier
static bool busvoodoo_spi_action(const char *action, uint32_t repetition, bool perform)
perform SPI action
global definitions and methods (API)
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
#define RCC_SPI_MISO_PORT(x)
get RCC for GPIO port for SPI MISO signals
static bool busvoodoo_spi_pullup
if embedded pull-up resistors are used
#define RCC_SPI_MOSI_PORT(x)
get RCC for GPIO port for SPI MOSI signals
static uint8_t busvoodoo_spi_standard_mode
SPI mode (defining clock polarity and phase)
#define RCC_SPI(x)
get RCC for SPI based on SPI identifier
#define SPI_NSS_PIN(x)
get SPI pin for NSS signal based on SPI identifier
static uint8_t busvoodoo_spi_baudrate
SPI baud rate (corresponding to baud rate control, e.g.
static void busvoodoo_spi_exit(void)
exit SPI mode
#define SPI_SCK_PORT(x)
get SPI port for SCK signal based on SPI identifier
struct busvoodoo_mode_t busvoodoo_spi_mode
SPI mode interface definition.
const char * busvoodoo_global_pinout_io[10]
I/O connector pinout.
char busvoodoo_global_string[64]
shared string buffer, i.e.
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
void sleep_ms(uint32_t duration)
go to sleep for some milliseconds
#define SPI_MISO_PORT(x)
get SPI port for MISO signal based on SPI identifier
static void busvoodoo_spi_write(uint16_t value)
write to SPI
size_t printf(const char *format,...)
print format string on user output
#define SPI(x)
get SPI based on SPI identifier
printing utilities to replace the large printf from the standard library (API)
#define RCC_SPI_SCK_PORT(x)
get RCC for GPIO port for SPI SCK signals
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
#define LENGTH(x)
get the length of an array
static const struct menu_command_t busvoodoo_spi_commands[]
SPI menu commands.
static uint8_t busvoodoo_spi_databits
SPI data frame bit width (8 or 16)
static bool busvoodoo_spi_duplex
SPI duplex mode (true = full-duplex, false = bidirectional)
#define SPI_MISO_PIN(x)
get SPI pin for MISO signal based on SPI identifier
library to show BusVoodoo mode information on SSD1306 OLED display: name, activity, pinout (API)
static void busvoodoo_spi_read(void)
read from SPI
static bool busvoodoo_spi_bitorder
SPI data frame bit order (true = MSb first, false = LSb first)
#define RCC_SPI_NSS_PORT(x)
get RCC for GPIO port for SPI NSS signals
BusVoodoo mode interface.
#define SPI_SCK_PIN(x)
get SPI pin for SCK signal based on SPI identifier