Skip to content
Snippets Groups Projects
Select Git revision
  • 3be21c8f4ffadb5b8a2173dc62258c9cf1666ab6
  • master default protected
  • embedded_programming
  • maybe-unnecessary
4 results

14_audio_interface.sch

Blame
  • main.cpp 9.28 KiB
    #include <Arduino.h>
    
    #include "indicators.h"
    #include "drivers/step_a4950.h"
    #include "osape-d51/osape/osap/osap.h"
    #include "osape-d51/vertices/vt_usbSerial.h"
    #include "osape-d51/vertices/ucbus/vt_ucBusDrop.h"
    #include "osape-d51/vertices/ucbus/ucBusDrop.h"
    
    // bare defaults: use vm / bus id to set on startup 
    uint8_t axis_pick = 0;
    float spu = 400.0F;
    float old_spu = 400.0F;
    volatile boolean spu_was_set = false;
    float c_scale = 0.00F;
    #define TICKS_PER_PACKET 25.0F
    #define TICKS_PER_SECOND 50000.0F
    
    // -------------------------------------------------------- AXIS PICK EP 
    
    EP_ONDATA_RESPONSES onAxisPickData(uint8_t* data, uint16_t len){
      if(data[0] > 3){
        axis_pick = 0;
      } else {
        axis_pick = data[0];
      }
      return EP_ONDATA_ACCEPT;
    }
    
    vertex_t* axisPickEp = osapBuildEndpoint("axisPick", onAxisPickData, nullptr);
    
    // -------------------------------------------------------- AXIS INVERSION EP
    
    EP_ONDATA_RESPONSES onAxisInvertData(uint8_t* data, uint16_t len){
      if(data[0] > 0){
        stepper_hw->setInversion(true);
      } else {
        stepper_hw->setInversion(false);
      }
      return EP_ONDATA_ACCEPT;
    }
    
    vertex_t* axisInvertEp = osapBuildEndpoint("axisInvert", onAxisInvertData, nullptr);
    
    // -------------------------------------------------------- MICROSTEP EP 
    
    EP_ONDATA_RESPONSES onMicrostepData(uint8_t* data, uint16_t len){
      stepper_hw->setMicrostep(data[0]);
      return EP_ONDATA_ACCEPT;
    }
    
    vertex_t* microstepEp = osapBuildEndpoint("microstep", onMicrostepData, nullptr);
    
    // -------------------------------------------------------- SPU EP
    
    EP_ONDATA_RESPONSES onSPUData(uint8_t* data, uint16_t len){
      chunk_float32 spuc = { .bytes = { data[0], data[1], data[2], data[3] } };
      old_spu = spu;
      spu = fabsf(spuc.f);
      spu_was_set = true;
      return EP_ONDATA_ACCEPT;
    }
    
    vertex_t* spuEp = osapBuildEndpoint("SPU", onSPUData, nullptr);
    
    // -------------------------------------------------------- CSCALE DATA
    
    EP_ONDATA_RESPONSES onCScaleData(uint8_t* data, uint16_t len){
      chunk_float32 cscalec = { .bytes = { data[0], data[1], data[2], data[3] } };
      if(cscalec.f > 1.0F){
        cscalec.f = 1.0F;
      } else if (cscalec.f < 0.0F){
        cscalec.f = 0.0F;
      }
      stepper_hw->setCurrent(cscalec.f);
      return EP_ONDATA_ACCEPT;
    }
    
    vertex_t* cScaleEp = osapBuildEndpoint("CScale", onCScaleData, nullptr);
    
    // -------------------------------------------------------- HOME ROUTINE
    
    // some homeing globals, 
    #define HOME_NOT 0
    #define HOME_FIRST 1
    #define HOME_BACKOFF 2
    
    uint8_t homing = 0;           // statemachine 
    float homeStepCounter = 0.0F; // step-float-counter
    float homePos = 0.0F;         // position (units)
    float homeStepRate = 0.0F;    // rate (steps/tick)
    float homePosRate = 0.0F;     // rate (units/tick)
    boolean homeDir = false;      // direction 
    float homeOffset = 0.0F;      // after-home offset 
    
    EP_ONDATA_RESPONSES onHomeData(uint8_t* data, uint16_t len){
      chunk_float32 rate = { .bytes = { data[0], data[1], data[2], data[3] } };
      chunk_float32 offset = { .bytes = { data[4], data[5], data[6], data[7] } };
      homing = HOME_FIRST;
      homeStepCounter = 0.0F;
      if(rate.f > 0){
        homeDir = true;
        stepper_hw->dir(true);
      } else {
        homeDir = false;
        stepper_hw->dir(false);
      }
      homeStepRate = abs(rate.f * spu) / TICKS_PER_SECOND;
      homePosRate = abs(rate.f) / TICKS_PER_SECOND;
      homeOffset = offset.f;
      return EP_ONDATA_ACCEPT;
    }
    
    vertex_t* homeEp = osapBuildEndpoint("Home", onHomeData, nullptr);
    
    // -------------------------------------------------------- HOME STATE 
    
    boolean beforeHomeStateQuery(void);
    
    vertex_t* homeStateEp = osapBuildEndpoint("HomeState", nullptr, beforeHomeStateQuery);
    
    boolean beforeHomeStateQuery(void){
      homeStateEp->ep->data[0] = homing;
      homeStateEp->ep->dataLen = 1;
      return true;
    }
    
    // -------------------------------------------------------- LIMIT SETUP 
    
    #define LIMIT_PORT PORT->Group[0]
    #define LIMIT_PIN 23 
    #define LIMIT_BM ((uint32_t)(1 << LIMIT_PIN))
    
    void limitSetup(void){
      // not-an-output 
      LIMIT_PORT.DIRCLR.reg = LIMIT_BM;
      // enable input 
      LIMIT_PORT.PINCFG[LIMIT_PIN].bit.INEN = 1;
      // enable pull 
      LIMIT_PORT.PINCFG[LIMIT_PIN].bit.PULLEN = 1;
      // 'pull' references direction from 'out' register, so we set hi to pull up (switch pulls to gnd)
      LIMIT_PORT.OUTSET.reg = LIMIT_BM;
    }
    
    boolean limitIsMade(void){
      // return true if switch is hit 
      return (LIMIT_PORT.IN.reg & LIMIT_BM);
    }
    
    void setup() {
      ERRLIGHT_SETUP;
      CLKLIGHT_SETUP;
      DEBUG1PIN_SETUP;
      // limit switch 
      //limitSetup();
      // osap
      osapSetup();
      // ports 
      vt_usbSerial_setup();
      osapAddVertex(vt_usbSerial);    // 0
      vt_ucBusDrop_setup();
      osapAddVertex(vt_ucBusDrop);    // 1
      // axis pick 
      osapAddVertex(axisPickEp);      // 2
      // axis invert
      osapAddVertex(axisInvertEp);    // 3
      // microstep 
      osapAddVertex(microstepEp);     // 4
      // SPU 
      osapAddVertex(spuEp);           // 5
      // cscale 
      osapAddVertex(cScaleEp);        // 6
      // homing 
      osapAddVertex(homeEp);          // 7 
      osapAddVertex(homeStateEp);     // 8 
      // stepper init 
      stepper_hw->init(false, c_scale);
    }
    
    uint8_t testRx[256];
    
    void loop() {
      osapLoop();
      stepper_hw->dacRefresh();
      // still not sure: this registers as "made" on init (?) 
      if(limitIsMade()){
        ERRLIGHT_ON;
      } else {
        ERRLIGHT_OFF;
      }
    } // end loop 
    
    
    volatile float current_floating_pos = 0.0F;
    volatile int32_t current_step_pos = 0;
    volatile uint32_t delta_steps = 0;
    
    volatile float vel = 0.0F; 
    volatile float move_counter = 0.0F;
    
    volatile boolean setBlock = false;
    
    void ucBusDrop_onPacketARx(uint8_t* inBufferA, volatile uint16_t len){
      // don't execute when we have been given a set-position block 
      if(setBlock) return;
      // don't execute if we are currently homing
      if(homing) return;
      //DEBUG2PIN_TOGGLE;
      // last move is done, convert back steps -> float,
      if(spu_was_set){
        current_floating_pos = current_step_pos / old_spu;
        current_step_pos = lroundf(current_floating_pos * spu);
        spu_was_set = false;
      } else {
        current_floating_pos = current_step_pos / spu;
      }
      vel = 0.0F; // reset zero in case packet is not move 
      uint8_t bptr = 0;
      // switch bus packet types 
      switch(inBufferA[0]){
        case UB_AK_GOTOPOS:
          {
            bptr = axis_pick * 4 + 1;
            chunk_float32 target = {
              .bytes = { inBufferA[bptr], inBufferA[bptr + 1], inBufferA[bptr + 2], inBufferA[bptr + 3] }
            };
            /*
            chunk_float64 target = { 
              .bytes = { inBuffer[bptr], inBuffer[bptr + 1], inBuffer[bptr + 2], inBuffer[bptr + 3],
                        inBuffer[bptr + 4], inBuffer[bptr + 5], inBuffer[bptr + 6], inBuffer[bptr + 7] }};
                        */
            float delta = target.f - current_floating_pos;
            // update,
            //move_counter = 0.0F; // shouldn't need this ? try deleting 
            // direction swop,
            if(delta > 0){
              stepper_hw->dir(true);
            } else {
              stepper_hw->dir(false);
            }
            // how many steps, 
            delta_steps = lroundf(abs(delta * spu));
            // what speed 
            vel = abs(delta * spu) / TICKS_PER_PACKET;
            // for str8 r8 
            /*
            if(delta_steps == 0){
              vel = 0.0F;
            } else {
              vel = abs(delta * SPU) / TICKS_PER_PACKET;
            }
            */
            break; // end gotopos 
          }
        case UB_AK_SETPOS:
          {
            // reqest is to set position, not go to it... 
            bptr = axis_pick * 4 + 1;
            chunk_float32 target = {
              .bytes = { inBufferA[bptr], inBufferA[bptr + 1], inBufferA[bptr + 2], inBufferA[bptr + 3] }
            };
            float target_current_pos = target.f;
            int32_t target_current_steps = lroundf(target_current_pos * spu);
            setBlock = true; // don't do step work while these are modified 
            current_floating_pos = target_current_pos;
            current_step_pos = target_current_steps;
            vel = 0;
            delta_steps = 0;
            setBlock = false;
            break;
          }
        default:
          break;
      }  
      //DEBUG2PIN_OFF;
    }
    
    void ucBusDrop_onRxISR(void){
      // no-op when given a set block, 
      if(setBlock) return;
      // incremental motion if is homing 
      if(homing != 0){
        switch(homing){
          case HOME_FIRST:
            if(limitIsMade()){
              // traaaaaaansition -> backoff 
              stepper_hw->dir(!homeDir);
              homeStepCounter = 0.0F;
              homePos = 0.0F;
              homing = HOME_BACKOFF;
            } else {
              homeStepCounter += homeStepRate;
              if(homeStepCounter >= 1.0F){
                homeStepCounter -= 1.0F;
                stepper_hw->step();
              }
            }
            break;
          case HOME_BACKOFF:
            homeStepCounter += homeStepRate;
            homePos += homePosRate;
            if(homeStepCounter >= 1.0F){  // backoff motion 
              homeStepCounter -= 1.0F;
              stepper_hw->step();
            }
            if(homePos >= homeOffset){ // until more than 2mm away 
              // traaaaaaaaaaaaaansition -> end 
              homing = 0;
            }
            break;
          default:
            homing = 0;
        }
        return;
      }
      // normal step operation 
      //DEBUG2PIN_TOGGLE;
      move_counter += vel;
      boolean move_check = (move_counter > 1.0F);
      //DEBUG2PIN_TOGGLE;
      if(move_check){
        move_counter -= 1.0F;
        if(delta_steps == 0){
          // nothing 
        } else {
          //DEBUG1PIN_TOGGLE;
          stepper_hw->step();
          delta_steps --;
          if(stepper_hw->getDir()){
            current_step_pos ++;
          } else {
            current_step_pos --;
          }
        }
      }
    }