#include "config.h"
#include "encoder.h"
-/**** Allocate Structures ****/
-
enEncoders_t en;
-/*
- * encoder_init() - initialize encoders
- */
-
-void encoder_init()
-{
- memset(&en, 0, sizeof(en)); // clear all values, pointers and status
- encoder_init_assertions();
+void encoder_init() {
+ memset(&en, 0, sizeof(en)); // clear all values, pointers and status
+ encoder_init_assertions();
}
-/*
- * encoder_init_assertions() - initialize encoder assertions
- * encoder_test_assertions() - test assertions, return error code if violation exists
- */
-void encoder_init_assertions()
-{
- en.magic_end = MAGICNUM;
- en.magic_start = MAGICNUM;
+void encoder_init_assertions() {
+ en.magic_end = MAGICNUM;
+ en.magic_start = MAGICNUM;
}
-stat_t encoder_test_assertions()
-{
- if (en.magic_end != MAGICNUM) return STAT_ENCODER_ASSERTION_FAILURE;
- if (en.magic_start != MAGICNUM) return STAT_ENCODER_ASSERTION_FAILURE;
- return STAT_OK;
+
+stat_t encoder_test_assertions() {
+ if (en.magic_end != MAGICNUM) return STAT_ENCODER_ASSERTION_FAILURE;
+ if (en.magic_start != MAGICNUM) return STAT_ENCODER_ASSERTION_FAILURE;
+
+ return STAT_OK;
}
+
/*
- * en_set_encoder_steps() - set encoder values to a current step count
+ * Set encoder values to a current step count
*
* Sets the encoder_position steps. Takes floating point steps as input,
* writes integer steps. So it's not an exact representation of machine
* position except if the machine is at zero.
*/
-
-void en_set_encoder_steps(uint8_t motor, float steps)
-{
- en.en[motor].encoder_steps = (int32_t)round(steps);
+void en_set_encoder_steps(uint8_t motor, float steps) {
+ en.en[motor].encoder_steps = (int32_t)round(steps);
}
+
/*
- * en_read_encoder()
- *
* The stepper ISR count steps into steps_run(). These values are accumulated to
* encoder_position during LOAD (HI interrupt level). The encoder position is
* therefore always stable. But be advised: the position lags target and position
* valaues elsewherein the system becuase the sample is taken when the steps for
* that segment are complete.
*/
-
-float en_read_encoder(uint8_t motor)
-{
- return (float)en.en[motor].encoder_steps;
+float en_read_encoder(uint8_t motor) {
+ return (float)en.en[motor].encoder_steps;
}
* these points. This synchronization is taken care of by the Target, Position, Position_delayed
* sequence in plan_exec. Referring to ASCII art in stepper.h and reproduced here:
*
- * LOAD/STEP (~5000uSec) [L1][Segment1][L2][Segment2][L3][Segment3][L4][Segment4][Lb1][Segmentb1]
- * PREP (100 uSec) [P1] [P2] [P3] [P4] [Pb1] [Pb2]
- * EXEC (400 uSec) [EXEC1] [EXEC2] [EXEC3] [EXEC4] [EXECb1] [EXECb2]
+ * LOAD/STEP (~5000uSec) [L1][Segment1][L2][Segment2][L3][Segment3][L4][Segment4][Lb1][Segmentb1]
+ * PREP (100 uSec) [P1] [P2] [P3] [P4] [Pb1] [Pb2]
+ * EXEC (400 uSec) [EXEC1] [EXEC2] [EXEC3] [EXEC4] [EXECb1] [EXECb2]
* PLAN (<4ms) [PLANmoveA][PLANmoveB][PLANmoveC][PLANmoveD][PLANmoveE] etc.
*
* You can collect the target for moveA as early as the end of [PLANmoveA]. The system will
* runtime (the EXEC), but the exec will have moved on to moveB by the time we need it. So moveA's
* target needs to be saved somewhere.
*/
+
/*
* ERROR CORRECTION
*
* correction will be applied to moveC. (It's possible to recompute the body of moveB, but it may
* not be worth the trouble).
*/
+
#ifndef ENCODER_H_ONCE
#define ENCODER_H_ONCE
-/**** Configs and Constants ****/
-
-/**** Macros ****/
// used to abstract the encoder code out of the stepper so it can be managed in one place
-
-#define SET_ENCODER_STEP_SIGN(m,s) en.en[m].step_sign = s;
+#define SET_ENCODER_STEP_SIGN(m, s) en.en[m].step_sign = s;
#define INCREMENT_ENCODER(m) en.en[m].steps_run += en.en[m].step_sign;
-#define ACCUMULATE_ENCODER(m) en.en[m].encoder_steps += en.en[m].steps_run; en.en[m].steps_run = 0;
+#define ACCUMULATE_ENCODER(m) en.en[m].encoder_steps += en.en[m].steps_run; en.en[m].steps_run = 0;
-/**** Structures ****/
-typedef struct enEncoder { // one real or virtual encoder per controlled motor
- int8_t step_sign; // set to +1 or -1
- int16_t steps_run; // steps counted during stepper interrupt
- int32_t encoder_steps; // counted encoder position in steps
+typedef struct enEncoder { // one real or virtual encoder per controlled motor
+ int8_t step_sign; // set to +1 or -1
+ int16_t steps_run; // steps counted during stepper interrupt
+ int32_t encoder_steps; // counted encoder position in steps
} enEncoder_t;
+
typedef struct enEncoders {
- magic_t magic_start;
- enEncoder_t en[MOTORS]; // runtime encoder structures
- magic_t magic_end;
+ magic_t magic_start;
+ enEncoder_t en[MOTORS]; // runtime encoder structures
+ magic_t magic_end;
} enEncoders_t;
extern enEncoders_t en;
-/**** FUNCTION PROTOTYPES ****/
-
void encoder_init();
void encoder_init_assertions();
stat_t encoder_test_assertions();
void en_set_encoder_steps(uint8_t motor, float steps);
float en_read_encoder(uint8_t motor);
-#endif // End of include guard: ENCODER_H_ONCE
+#endif // ENCODER_H_ONCE
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
+
/*
* This GPIO file is where all parallel port bits are managed that are
* not already taken up by steppers, serial ports, SPI or PDI programming
*
* There are 2 GPIO ports:
*
- * gpio1 Located on 5x2 header next to the PDI programming plugs (on v7's)
- * Four (4) output bits capable of driving 3.3v or 5v logic
+ * gpio1 Located on 5x2 header next to the PDI programming plugs (on v7's)
+ * Four (4) output bits capable of driving 3.3v or 5v logic
*
* Note: On v6 and earlier boards there are also 4 inputs:
- * Four (4) level converted input bits capable of being driven
- * by 3.3v or 5v logic - connected to B0 - B3 (now used for SPI)
+ * Four (4) level converted input bits capable of being driven
+ * by 3.3v or 5v logic - connected to B0 - B3 (now used for SPI)
*
- * gpio2 Located on 9x2 header on "bottom" edge of the board
- * Eight (8) non-level converted input bits
- * Eight (8) ground pins - one each "under" each input pin
- * Two (2) 3.3v power pins (on left edge of connector)
- * Inputs can be used as switch contact inputs or
- * 3.3v input bits depending on port configuration
- * **** These bits CANNOT be used as 5v inputs ****
+ * gpio2 Located on 9x2 header on "bottom" edge of the board
+ * Eight (8) non-level converted input bits
+ * Eight (8) ground pins - one each "under" each input pin
+ * Two (2) 3.3v power pins (on left edge of connector)
+ * Inputs can be used as switch contact inputs or
+ * 3.3v input bits depending on port configuration
+ * **** These bits CANNOT be used as 5v inputs ****
*/
#include <avr/interrupt.h>
#include "gpio.h"
#include "canonical_machine.h"
-//======================== Parallel IO Functions ===============================
-/*
- * IndicatorLed_set() - fake out for IndicatorLed.set() until we get Motate running
- * IndicatorLed_clear() - fake out for IndicatorLed.clear() until we get Motate running
- * IndicatorLed_toggle()- fake out for IndicatorLed.toggle() until we get Motate running
- */
+void indicator_led_set() {
+ gpio_led_on(INDICATOR_LED);
+ cs.led_state = 1;
+}
+
-void IndicatorLed_set()
-{
- gpio_led_on(INDICATOR_LED);
- cs.led_state = 1;
+void indicator_led_clear() {
+ gpio_led_off(INDICATOR_LED);
+ cs.led_state = 0;
}
-void IndicatorLed_clear()
-{
- gpio_led_off(INDICATOR_LED);
- cs.led_state = 0;
+
+void indicator_led_toggle() {
+ gpio_led_toggle(INDICATOR_LED);
+ cs.led_state = !cs.led_state;
}
-void IndicatorLed_toggle()
-{
- if (cs.led_state == 0) {
- gpio_led_on(INDICATOR_LED);
- cs.led_state = 1;
- } else {
- gpio_led_off(INDICATOR_LED);
- cs.led_state = 0;
- }
+
+void gpio_led_on(uint8_t led) {
+ gpio_set_bit_on(8 >> led);
}
-/*
- * gpio_led_on() - turn led on - assumes TinyG LED mapping
- * gpio_led_off() - turn led on - assumes TinyG LED mapping
- * gpio_led_toggle()
- */
-void gpio_led_on(uint8_t led)
-{
- if (led == 0) gpio_set_bit_on(0x08); else
- if (led == 1) gpio_set_bit_on(0x04); else
- if (led == 2) gpio_set_bit_on(0x02); else
- if (led == 3) gpio_set_bit_on(0x01);
+void gpio_led_off(uint8_t led) {
+ gpio_set_bit_off(8 >> led);
}
-void gpio_led_off(uint8_t led)
-{
- if (led == 0) gpio_set_bit_off(0x08); else
- if (led == 1) gpio_set_bit_off(0x04); else
- if (led == 2) gpio_set_bit_off(0x02); else
- if (led == 3) gpio_set_bit_off(0x01);
+
+void gpio_led_toggle(uint8_t led) {
+ gpio_set_bit_toggle(8 >> led);
}
-void gpio_led_toggle(uint8_t led)
-{
- if (led == 0) {
- if (gpio_read_bit(0x08)) {
- gpio_set_bit_off(0x08);
- } else {
- gpio_set_bit_on(0x08);
- }
- } else if (led == 1) {
- if (gpio_read_bit(0x04)) {
- gpio_set_bit_off(0x04);
- } else {
- gpio_set_bit_on(0x04);
- }
- } else if (led == 2) {
- if (gpio_read_bit(0x02)) {
- gpio_set_bit_off(0x02);
- } else {
- gpio_set_bit_on(0x02);
- }
- } else if (led == 3) {
- if (gpio_read_bit(0x08)) {
- gpio_set_bit_off(0x08);
- } else {
- gpio_set_bit_on(0x08);
- }
- }
+
+uint8_t gpio_read_bit(uint8_t b) {
+ if (b & 0x08) return hw.out_port[0]->IN & GPIO1_OUT_BIT_bm;
+ if (b & 0x04) return hw.out_port[1]->IN & GPIO1_OUT_BIT_bm;
+ if (b & 0x02) return hw.out_port[2]->IN & GPIO1_OUT_BIT_bm;
+ if (b & 0x01) return hw.out_port[3]->IN & GPIO1_OUT_BIT_bm;
+
+ return 0;
}
-/*
- * gpio_read_bit() - return true if bit is on, false if off
- * gpio_set_bit_on() - turn bit on
- * gpio_set_bit_off() - turn bit on
- *
- * These functions have an inner remap depending on what hardware is running
- */
-uint8_t gpio_read_bit(uint8_t b)
-{
- if (b & 0x08) { return hw.out_port[0]->IN & GPIO1_OUT_BIT_bm; }
- if (b & 0x04) { return hw.out_port[1]->IN & GPIO1_OUT_BIT_bm; }
- if (b & 0x02) { return hw.out_port[2]->IN & GPIO1_OUT_BIT_bm; }
- if (b & 0x01) { return hw.out_port[3]->IN & GPIO1_OUT_BIT_bm; }
- return 0;
+void gpio_set_bit_on(uint8_t b) {
+ if (b & 0x08) hw.out_port[0]->OUTSET = GPIO1_OUT_BIT_bm;
+ if (b & 0x04) hw.out_port[1]->OUTSET = GPIO1_OUT_BIT_bm;
+ if (b & 0x02) hw.out_port[2]->OUTSET = GPIO1_OUT_BIT_bm;
+ if (b & 0x01) hw.out_port[3]->OUTSET = GPIO1_OUT_BIT_bm;
}
-void gpio_set_bit_on(uint8_t b)
-{
- if (b & 0x08) { hw.out_port[0]->OUTSET = GPIO1_OUT_BIT_bm; }
- if (b & 0x04) { hw.out_port[1]->OUTSET = GPIO1_OUT_BIT_bm; }
- if (b & 0x02) { hw.out_port[2]->OUTSET = GPIO1_OUT_BIT_bm; }
- if (b & 0x01) { hw.out_port[3]->OUTSET = GPIO1_OUT_BIT_bm; }
+
+void gpio_set_bit_off(uint8_t b) {
+ if (b & 0x08) hw.out_port[0]->OUTCLR = GPIO1_OUT_BIT_bm;
+ if (b & 0x04) hw.out_port[1]->OUTCLR = GPIO1_OUT_BIT_bm;
+ if (b & 0x02) hw.out_port[2]->OUTCLR = GPIO1_OUT_BIT_bm;
+ if (b & 0x01) hw.out_port[3]->OUTCLR = GPIO1_OUT_BIT_bm;
}
-void gpio_set_bit_off(uint8_t b)
-{
- if (b & 0x08) { hw.out_port[0]->OUTCLR = GPIO1_OUT_BIT_bm; }
- if (b & 0x04) { hw.out_port[1]->OUTCLR = GPIO1_OUT_BIT_bm; }
- if (b & 0x02) { hw.out_port[2]->OUTCLR = GPIO1_OUT_BIT_bm; }
- if (b & 0x01) { hw.out_port[3]->OUTCLR = GPIO1_OUT_BIT_bm; }
+
+void gpio_set_bit_toggle(uint8_t b) {
+ if (b & 0x08) hw.out_port[0]->OUTTGL = GPIO1_OUT_BIT_bm;
+ if (b & 0x04) hw.out_port[1]->OUTTGL = GPIO1_OUT_BIT_bm;
+ if (b & 0x02) hw.out_port[2]->OUTTGL = GPIO1_OUT_BIT_bm;
+ if (b & 0x01) hw.out_port[3]->OUTTGL = GPIO1_OUT_BIT_bm;
}