summaryrefslogtreecommitdiff
path: root/software_pwm.c
diff options
context:
space:
mode:
authorBrett Weiland <brett_weiland@bpcspace.com>2023-10-27 07:10:26 -0500
committerBrett Weiland <brett_weiland@bpcspace.com>2023-10-27 07:10:26 -0500
commite811d778ea51ac1e25588a9cc957fca4f532ea5a (patch)
treed28999567bad4613143d016bfb6d376c22f9e3a2 /software_pwm.c
init
Diffstat (limited to 'software_pwm.c')
-rw-r--r--software_pwm.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/software_pwm.c b/software_pwm.c
new file mode 100644
index 0000000..561edfd
--- /dev/null
+++ b/software_pwm.c
@@ -0,0 +1,89 @@
+#include <stdint.h>
+#include <string.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <stdbool.h>
+#include <stddef.h>
+
+#include "software_pwm.h"
+#include "pins.h"
+
+
+static struct link_pair {
+ struct pwm_event *next;
+ struct pwm_event *prev;
+};
+
+//if next is ever zero, node is assumed not part of list/disabled
+static struct pwm_event {
+ struct link_pair active;
+ struct link_pair twins;
+ uint8_t time;
+ uint8_t pins;
+ bool enabled;
+} events[SOFTPWM_PIN_COUNT + 1];
+
+
+#define LIST_INSERT(new, former, member) (\
+ list_insert(&(new.member), &(former.member), offsetof(struct pwm_event, time)))
+
+static void list_insert(struct link_pair *new_links, struct link_pair *former_links, size_t parent_offset) {
+
+}
+
+static void list_remove(struct link_pair *event) {
+}
+
+void init_softpwm() {
+
+ //this one never moves
+ events[SOFTPWM_PIN_COUNT].time = 0;
+ events[SOFTPWM_PIN_COUNT].pins = 0;
+ events[SOFTPWM_PIN_COUNT].active.next = &events[SOFTPWM_PIN_COUNT];
+ events[SOFTPWM_PIN_COUNT].active.prev = &events[SOFTPWM_PIN_COUNT];
+ events[SOFTPWM_PIN_COUNT].enabled = true;
+
+ //TODO: move all to zero once init_softpwm tested
+ for(size_t event_i = 0; event_i < SOFTPWM_PIN_COUNT; event_i++) {
+ events[event_i].time = event_i;
+ events[event_i].pins = (1 << (event_i + 1)) - 1;
+ LIST_INSERT(events[event_i], events[((int)event_i - 1) % (SOFTPWM_PIN_COUNT + 1)], active);
+ }
+
+ SOFTPWM_DDR = 0xff;
+
+ //use external 10mhz clock (we just have one laying around)
+ //then prescale by 1024. Check at different freqs for brightness
+ TCCR0A = 0b00000010;
+ TIMSK0 = 0b00000011;
+ OCR0A = events[SOFTPWM_PIN_COUNT].time;
+ TIFR0 = 0b00000010; //interupts enabled!
+ sei();
+}
+
+void softpwm_set(uint8_t pin, uint8_t duty) {
+ /**
+ struct pwm_event *event_unmoved = &events[pin]; //TODO describe if you want ig
+ struct pwm_event *this_event = &events[pin];
+ this_event->time = duty;
+ if(duty < events[pin].time) {
+ while(duty < event_unmoved->time) event_unmoved = event_unmoved->next;
+ }
+ else {
+ }
+ **/
+}
+
+/**
+ISR(TIMER0_OVF_vect) {
+}
+**/
+
+ISR(TIMER0_COMP_vect) {
+ /**
+ static struct pwm_event *on_event = &events[SOFTPWM_PIN_COUNT];
+ SOFTPWM_PORT = on_event->pins;
+ on_event = on_event->next;
+ OCR0A = on_event->time;
+ **/
+}