diff --git a/.vscode/settings.json b/.vscode/settings.json index 55dd4d4..011e21c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,10 @@ { "C_Cpp.errorSquiggles": "Enabled", "files.associations": { - "pwm.h": "c" + "pwm.h": "c", + "ftdi.h": "c", + "bridge.h": "c", + "pins.h": "c", + "stdio.h": "c" } } \ No newline at end of file diff --git a/Makefile b/Makefile index 0445bdd..f7687f3 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ -TARGETNAME = togglePin +TARGETNAME = inverter BUILDFOLDER = ./build/ TARGET = $(BUILDFOLDER)$(TARGETNAME) -INC = -Isrc/include -I/usr/avr/include -CFLAGS = -Wall -Wpedantic -Wextra -Os -mmcu=atmega32u4 -CPPFLAGS = -DF_CPU=16000000UL +INC = -Isrc/include -I/usr/include -I/usr/include/libftdi1 +CFLAGS = -Wall -Wpedantic -Wextra -Os +CPPFLAGS = SRC = $(wildcard src/*.c) @@ -12,12 +12,7 @@ all: $(TARGET) $(TARGET): $(SRC) mkdir -p build - avr-gcc -o $@.elf $^ $(CPPFLAGS) $(CFLAGS) $(INC) -Wl,-u,vfprintf -lprintf_flt -lm - avr-objcopy -j .text -j .data -O ihex $@.elf $@.hex - rm $@.elf - -flash: - avrdude -p m32u4 -P /dev/ttyACM0 -c stk500v2 -Uflash:w:"$(TARGET).hex":i + gcc -o $@ $^ $(CPPFLAGS) $(CFLAGS) $(INC) -lm -lftdi1 clean: rm -fr ./src/*.o ./build/ diff --git a/build/inverter b/build/inverter new file mode 100755 index 0000000..d2fc28b Binary files /dev/null and b/build/inverter differ diff --git a/src/bridge.c b/src/bridge.c deleted file mode 100644 index 00e5d12..0000000 --- a/src/bridge.c +++ /dev/null @@ -1,102 +0,0 @@ - -#include "bridge.h" -#include "statemachine.h" -#include "pins.h" - - -bdg_sm_state_t bridge_state; - -sm_trans_t bridge_sm_transitions[] = -{ - { - .from_state = BRIDGE_SM_START, - .to_state = BRIDGE_SM_INIT_IO, - .trans_fct = brdg_BothGndOn - }, - { - .from_state = BRIDGE_SM_INIT_IO, - .to_state = HB1_PWR_ON, - .trans_fct = brdg_Hb1PowerOn - }, - { - .from_state = HB1_GND_ON, - .to_state = HB1_PWR_ON, - .trans_fct = brdg_Hb1PowerOn - }, - { - .from_state = HB1_PWR_ON, - .to_state = HB1_PWR_OFF, - .trans_fct = brdg_Hb1PowerOff - }, - { - .from_state = HB1_PWR_OFF, - .to_state = HB2_GND_ON, - .trans_fct = brdg_Hb2GndOn - }, - { - .from_state = HB2_GND_ON, - .to_state = HB2_PWR_ON, - .trans_fct = brdg_Hb2PowerOn - }, - { - .from_state = HB2_PWR_ON, - .to_state = HB2_PWR_OFF, - .trans_fct = brdg_Hb2PowerOff - }, - { - .from_state = HB2_PWR_OFF, - .to_state = HB2_GND_ON, - .trans_fct = brdg_Hb2GndOn - } -}; - -sm_t bridge_statemachine = { - .current_state = BRIDGE_SM_START, - .transitions = bridge_sm_transitions -}; - -void brdg_BothGndOn(void) -{ - /* Turn both GND transistors on */ - setPin(&PORTB, PB6); - setPin(&PORTB, PB4); - - /* Turn both PWR transistors off */ - unsetPin(&PORTB, PB7); - unsetPin(&PORTB, PB5); -} - -void brdg_Hb1GndOn(void) -{ - /* We turn GND of half-bridge 1 on */ - setPin(&PORTB, PB6); - - /* And then we turn GND of half-bridge 2 off */ - unsetPin(&PORTB, PB4); -} - -void brdg_Hb1PowerOn(void) -{ - setPin(&PORTB, PB7); -} - -void brdg_Hb1PowerOff(void) -{ - unsetPin(&PORTB, PB7); -} - -void brdg_Hb2GndOn(void) -{ - setPin(&PORTB, PB4); - unsetPin(&PORTB, PB6); -} - -void brdg_Hb2PowerOn(void) -{ - setPin(&PORTB, PB5); -} - -void brdg_Hb2PowerOff(void) -{ - unsetPin(&PORTB, PB5); -} diff --git a/src/bridge_utils.c b/src/bridge_utils.c new file mode 100644 index 0000000..ccd1cab --- /dev/null +++ b/src/bridge_utils.c @@ -0,0 +1,83 @@ + +#include "bridge_utils.h" +#include "statemachine.h" +#include "pins.h" + +bdg_sm_state_t bridge_state; + +sm_trans_t bridge_sm_transitions[] = + { + {.from_state = BRIDGE_SM_START, + .to_state = BRIDGE_SM_INIT_IO, + .trans_fct = brdg_BothGndOn}, + {.from_state = BRIDGE_SM_INIT_IO, + .to_state = HB1_PWR_ON, + .trans_fct = brdg_Hb1PowerOn}, + {.from_state = HB1_GND_ON, + .to_state = HB1_PWR_ON, + .trans_fct = brdg_Hb1PowerOn}, + {.from_state = HB1_PWR_ON, + .to_state = HB1_PWR_OFF, + .trans_fct = brdg_Hb1PowerOff}, + {.from_state = HB1_PWR_OFF, + .to_state = HB2_GND_ON, + .trans_fct = brdg_Hb2GndOn}, + {.from_state = HB2_GND_ON, + .to_state = HB2_PWR_ON, + .trans_fct = brdg_Hb2PowerOn}, + {.from_state = HB2_PWR_ON, + .to_state = HB2_PWR_OFF, + .trans_fct = brdg_Hb2PowerOff}, + {.from_state = HB2_PWR_OFF, + .to_state = HB2_GND_ON, + .trans_fct = brdg_Hb2GndOn}}; + +sm_t bridge_statemachine = { + .current_state = BRIDGE_SM_START, + .transitions = bridge_sm_transitions}; + +void brdg_BothGndOn(void) +{ + /* Turn both GND transistors on */ + setPin(PB6); + setPin(PB4); + + /* Turn both PWR transistors off */ + unsetPin(PB7); + unsetPin(PB5); +} + +void brdg_Hb1GndOn(void) +{ + /* We turn GND of half-bridge 1 on */ + setPin(PB6); + + /* And then we turn GND of half-bridge 2 off */ + unsetPin(PB4); +} + +void brdg_Hb1PowerOn(void) +{ + setPin(PB7); +} + +void brdg_Hb1PowerOff(void) +{ + unsetPin(PB7); +} + +void brdg_Hb2GndOn(void) +{ + setPin(PB4); + unsetPin(PB6); +} + +void brdg_Hb2PowerOn(void) +{ + setPin(PB5); +} + +void brdg_Hb2PowerOff(void) +{ + unsetPin(PB5); +} diff --git a/src/commands.c b/src/commands.c deleted file mode 100644 index 2b948e7..0000000 --- a/src/commands.c +++ /dev/null @@ -1,189 +0,0 @@ -#include -#include -#include -#include - -#include "commands.h" -#include "pins.h" -#include "uart.h" -#include "timer.h" - - -cmd_t command = { - .buf = {0}, - .index = 0 -}; - -int cmd_terminated = 0; - -void cmd_worker(void) -{ - cmd_handle(&command); -} - -void cmd_collect_char(char c) -{ - command.buf[command.index] = c; - command.index++; - - if (c == 0x3) { - /* React on Ctl-C */ - command.index = 0; - printf("\r\n"); - } - - if (c == 0xD) { - /* Null-terminate the string */ - command.buf[command.index-1] = '\0'; - - command.index = 0; - cmd_terminated = 1; - } - - /* We are switching the timer off here because serial - * line handling is iffy with timer on */ - if (c == 0x18) - printf("T1: %d\r\n",cmd_handle_switch_timer()); -} - -void cmd_handle(cmd_t *command) -{ - if (!cmd_terminated) - return; - - printf("\n\r"); - - char *tok1 = strtok(command->buf, " "); - char *tok2 = strtok(NULL, " "); - char *tok3 = strtok(NULL, " "); - - if (0 == strcmp(tok1, "set")) - cmd_handle_set(tok2, tok3); - - if (0 == strcmp(tok1, "switch") || 0 == strcmp(tok1, "sw")) - cmd_handle_switch(tok2, tok3); - - - cmd_terminated = 0; -} - -void cmd_handle_set(char *op1, char *op2) -{ - long int val; - char *end; - - if (0 == strcmp(op1, "t0_top")) { - val = strtol(op2, &end, 10); - if (op2 != end) { - OCR0A = val; - printf("Setting Timer0 TOP to %li\r\n", val); - } - else - printf("No valid value for t0_top given\n\r"); - } - else if (0 == strcmp(op1, "t1_top")) { - val = strtol(op2, &end, 10); - if (op2 != end) { - OCR1A = val; - printf("Setting Timer1 TOP to %li\r\n", val); - } - else - printf("No valid value for t1_top given\n\r"); - } - else if (0 == strcmp(op1, "t1_cm")) { - val = strtol(op2, &end, 10); - if (op2 != end) { - OCR1B = val; - printf("Setting Timer1 Compare Match to %li\r\n", val); - } - else - printf("No valid value for t1_cm given\n\r"); - } - else if (0 == strcmp(op1, "t0_ps")) { - val = strtol(op2, &end, 10); - TCCR0B &= ~((1 << CS00) | (1 << CS01) | (1 << CS02)); - switch (val) - { - case 0: - TCCR0B |= (1 << CS00); - break; - case 8: - TCCR0B |= (1 << CS01); - break; - case 64: - TCCR0B |= (1 << CS00) | (1 << CS01); - break; - case 256: - TCCR0B |= (1 << CS02); - break; - case 1024: - TCCR0B |= (1 << CS02) | (1 << CS00); - break; - default: - printf("No valid prescaler value.\n\r"); - break; - } - } -} - -void cmd_handle_switch(char *op1, char *op2) -{ - if (0 == strcmp(op1, "pd6")) { - if (0 == strcmp(op2, "on")) - setPin(&PORTD, PD6); - else if (0 == strcmp(op2, "off")) - unsetPin(&PORTD, PD6); - else - togglePin(&PORTD, PD6); - } - - if (0 == strcmp(op1, "pb6")) { - if (0 == strcmp(op2, "on")) - setPin(&PORTB, PB6); - else if (0 == strcmp(op2, "off")) - unsetPin(&PORTB, PB6); - else - togglePin(&PORTB, PB6); - } - - if (0 == strcmp(op1, "pc7")) { - if (0 == strcmp(op2, "on")) - setPin(&PORTC, PC7); - else if (0 == strcmp(op2, "off")) - unsetPin(&PORTC, PC7); - else - togglePin(&PORTC, PC7); - } - - if (0 == strcmp(op1, "pd1")) { - if (0 == strcmp(op2, "on")) - setPin(&PORTD, PD1); - else if (0 == strcmp(op2, "off")) - unsetPin(&PORTD, PD1); - else - togglePin(&PORTD, PD1); - } - - if (0 == strcmp(op1, "pd0")) { - if (0 == strcmp(op2, "on")) - setPin(&PORTD, PD0); - else if (0 == strcmp(op2, "off")) - unsetPin(&PORTD, PD0); - else - togglePin(&PORTD, PD0); - } -} - -int cmd_handle_switch_timer(void) -{ - static int timer1_on = 1; - - if (timer1_on) - tmr_disableT1(); - else - tmr_enableT1(); - - timer1_on = !timer1_on; - - return timer1_on; -} \ No newline at end of file diff --git a/src/ftdi_utils.c b/src/ftdi_utils.c new file mode 100644 index 0000000..2e0240f --- /dev/null +++ b/src/ftdi_utils.c @@ -0,0 +1,42 @@ +#include +#include +#include + +#include "ftdi_utils.h" + +struct ftdi_context *ftdi; + +int init_ftdi(){ + struct ftdi_version_info version; + uint8_t pins; + unsigned int chipid; + + if ((ftdi = ftdi_new()) == 0) + { + fprintf(stderr, "ftdi_new failed\n"); + return EXIT_FAILURE; + } + version = ftdi_get_library_version(); + printf("Initialized libftdi %s (major: %d, minor: %d, micro: %d, snapshot ver: %s)\n", + version.version_str, version.major, version.minor, version.micro, + version.snapshot_str); + + int ret = ftdi_usb_open(ftdi, 0x0403, 0x6014); + if (ret < 0) + { + fprintf(stderr, "unable to open ftdi device: %d (%s)\n", ret, ftdi_get_error_string(ftdi)); + ftdi_free(ftdi); + return EXIT_FAILURE; + } + + // Enable bitbang mode + ftdi_set_bitmode(ftdi, 0xFF, BITMODE_BITBANG); + + printf("ftdi_read_chipid: %d\n", ftdi_read_chipid(ftdi, &chipid)); + printf("FTDI chipid: %X\n", chipid); + ftdi_read_pins(ftdi, &pins); + + printf("Pins state: %X\n", pins); + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/src/include/bridge.h b/src/include/bridge_utils.h similarity index 100% rename from src/include/bridge.h rename to src/include/bridge_utils.h diff --git a/src/include/commands.h b/src/include/commands.h deleted file mode 100644 index 8378439..0000000 --- a/src/include/commands.h +++ /dev/null @@ -1,12 +0,0 @@ -typedef struct { - char buf[100]; - int index; -} cmd_t; - -void cmd_worker(void); - -void cmd_collect_char(char c); -void cmd_handle(cmd_t *command); -void cmd_handle_set(char *op1, char *op2); -void cmd_handle_switch(char *op1, char *op2); -int cmd_handle_switch_timer(void); \ No newline at end of file diff --git a/src/include/ftdi_utils.h b/src/include/ftdi_utils.h index e874937..b32f409 100644 --- a/src/include/ftdi_utils.h +++ b/src/include/ftdi_utils.h @@ -1,7 +1,3 @@ -#include - extern struct ftdi_context *ftdi; -ftdi_context* get_ftdi_context() { - return ftdi; -} \ No newline at end of file +int init_ftdi(); \ No newline at end of file diff --git a/src/include/pins.h b/src/include/pins.h index 6584b45..b0e2fae 100644 --- a/src/include/pins.h +++ b/src/include/pins.h @@ -1,8 +1,10 @@ #include +#define PB6 1 +#define PB4 2 +#define PB5 3 +#define PB7 4 -const uint8_t PORTB = 1; - -void togglePin(volatile uint8_t *port, unsigned int pin); -void unsetPin(volatile uint8_t *port, unsigned int pin); -void setPin(volatile uint8_t *port, unsigned int pin); \ No newline at end of file +void togglePin(unsigned int pin); +void unsetPin(unsigned int pin); +void setPin(unsigned int pin); \ No newline at end of file diff --git a/src/include/uart.h b/src/include/uart.h deleted file mode 100644 index edbfb28..0000000 --- a/src/include/uart.h +++ /dev/null @@ -1,5 +0,0 @@ -#include - -void uart_init(unsigned int baud); -void uart_sendByte(uint8_t byte); -int uart_printf(char var, FILE *stream); \ No newline at end of file diff --git a/src/inverter.c b/src/inverter.c index b1f9a87..ecdefa2 100644 --- a/src/inverter.c +++ b/src/inverter.c @@ -1,10 +1,6 @@ -#include -#include -#include -#include -#include "timer.h" -#include "commands.h" +#include + #include "pins.h" #include "pwm.h" @@ -12,24 +8,9 @@ int main() { + init_ftdi(); - if ((ftdi = ftdi_new()) == 0) - { - fprintf(stderr, "ftdi_new failed\n"); - return EXIT_FAILURE; - } - - pwm_init(); - tmr_initT1(); - tmr_enableT1(); - - printf("Up and running.\n\r"); - - while (1) - { - cmd_worker(); - pwm_worker(); - } + ftdi_free(ftdi); return 0; } diff --git a/src/pins.c b/src/pins.c index 50dad96..a3b24aa 100644 --- a/src/pins.c +++ b/src/pins.c @@ -1,23 +1,53 @@ #include #include +#include #include "pins.h" #include "ftdi_utils.h" -void setPin(volatile uint8_t *port, unsigned int pin) +uint8_t pin_state_cache = 0x0; + +void setPin(unsigned int pin) { - if (fftdi_write_data(ftdi, buf, 1)< 0) - { - fprintf(stderr, "write failed for 0x%x, error %d (%s)\n", buf[0], f, ftdi_get_error_string(ftdi)); - } + uint8_t pin_state = pin_state_cache | (1 << pin); + int ret = ftdi_write_data(ftdi, &pin_state, 1); + + if (ret < 0) + { + fprintf(stderr, "setting pin failed for data 0x%x, error %d (%s)\n", 1 << pin, ret, ftdi_get_error_string(ftdi)); + } + else + { + pin_state_cache = pin_state; + } } -void unsetPin(volatile uint8_t *port, unsigned int pin) +void unsetPin(unsigned int pin) { - *port &= ~(1 << pin); + uint8_t pin_state = pin_state_cache & ~(1 << pin); + int ret = ftdi_write_data(ftdi, &pin_state, 1); + + if (ret < 0) + { + fprintf(stderr, "unsetting pin failed for data 0x%x, error %d (%s)\n", 1 << pin, ret, ftdi_get_error_string(ftdi)); + } + else + { + pin_state_cache = pin_state; + } } -void togglePin(volatile uint8_t *port, unsigned int pin) +void togglePin(unsigned int pin) { - *port ^= (1 << pin); -} \ No newline at end of file + uint8_t pin_state = pin_state_cache ^ (1 << pin); + int ret = ftdi_write_data(ftdi, &pin_state, 1); + + if (ret < 0) + { + fprintf(stderr, "toggling pin failed for data 0x%x, error %d (%s)\n", 1 << pin, ret, ftdi_get_error_string(ftdi)); + } + else + { + pin_state_cache = pin_state; + } +} diff --git a/src/statemachine.c b/src/statemachine.c index 2076ecf..e1e1cda 100644 --- a/src/statemachine.c +++ b/src/statemachine.c @@ -2,5 +2,6 @@ void sm_handleTransition(sm_t *statemachine, sm_state_t to) { - + statemachine = statemachine; + to = to; } \ No newline at end of file diff --git a/src/uart.c b/src/uart.c deleted file mode 100644 index 73e0045..0000000 --- a/src/uart.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include - -#include "include/uart.h" -#include "include/commands.h" - -/* Make uart_printf be called whenever printf() is invoked */ -static FILE stream = FDEV_SETUP_STREAM(uart_printf, NULL, _FDEV_SETUP_WRITE); - -void uart_init(unsigned int baud) -{ - stdout = &stream; - - /* Set baud rate */ - UBRR1H = (unsigned char)(baud>>8); - UBRR1L = (unsigned char)baud; - - /* Enable receiver and transmitter */ - UCSR1B = (1<