diff --git a/firmware/axl-stepper/src/axl b/firmware/axl-stepper/src/axl index 202c44ee96ff46f07823a6dc8b9b4bb13c0a575e..2715834fbc79e77f061f0812234ab3a8eeb14f27 160000 --- a/firmware/axl-stepper/src/axl +++ b/firmware/axl-stepper/src/axl @@ -1 +1 @@ -Subproject commit 202c44ee96ff46f07823a6dc8b9b4bb13c0a575e +Subproject commit 2715834fbc79e77f061f0812234ab3a8eeb14f27 diff --git a/firmware/axl-stepper/src/main.cpp b/firmware/axl-stepper/src/main.cpp index 3b54a91277ef76d00002444f8591afb877f6c7e9..6d03ad580ed4059761117cf90e35fc9b84e26ba9 100644 --- a/firmware/axl-stepper/src/main.cpp +++ b/firmware/axl-stepper/src/main.cpp @@ -31,11 +31,11 @@ VBus_UCBusDrop vbUCBusDrop(&osap, "ucBusDrop"); // -------------------------------------------------------- 2: States EP_ONDATA_RESPONSES onStateData(uint8_t* data, uint16_t len){ - ERRLIGHT_TOGGLE; + /* // check for partner-config badness, if(len != AXL_NUM_DOF * 4 + 2){ OSAP::error("state req has bad DOF count"); return EP_ONDATA_REJECT; } // we have accel, rate, posn data, - dofs targ; + vect_t targ; uint16_t rptr = 0; uint8_t mode = data[rptr ++]; uint8_t set = data[rptr ++]; @@ -58,9 +58,9 @@ EP_ONDATA_RESPONSES onStateData(uint8_t* data, uint16_t len){ } } else { switch(mode){ - case AXL_MODE_ACCEL: - axl_setAccelTarget(targ); - break; + // case AXL_MODE_ACCEL: + // // axl_setAccelTarget(targ); + // break; case AXL_MODE_VELOCITY: axl_setVelocityTarget(targ); break; @@ -68,91 +68,75 @@ EP_ONDATA_RESPONSES onStateData(uint8_t* data, uint16_t len){ axl_setPositionTarget(targ); break; default: - OSAP::error("AXL state targ has bad / unrecognized mode"); + OSAP::error("AXL state targ has bad / unrecognized mode " + String(mode)); break; } } + */ // since we routinely update it w/ actual states (not requests) return EP_ONDATA_REJECT; } Endpoint statesEP(&osap, "states", onStateData); -void updateStatesEP(void){ - uint8_t numBytes = AXL_NUM_DOF * 4 * 3 + 2; - uint8_t stash[numBytes]; uint16_t wptr = 0; - stash[wptr ++] = axl_getMode(); - axl_isMoving() ? stash[wptr ++] = 1 : stash[wptr ++] = 0; - dofs temp = axl_getPositions(); - for(uint8_t a = 0; a < AXL_NUM_DOF; a ++){ - ts_writeFloat32(temp.axis[a], stash, &wptr); - } - temp = axl_getVelocities(); - for(uint8_t a = 0; a < AXL_NUM_DOF; a ++){ - ts_writeFloat32(temp.axis[a], stash, &wptr); - } - temp = axl_getAccelerations(); - for(uint8_t a = 0; a < AXL_NUM_DOF; a ++){ - ts_writeFloat32(temp.axis[a], stash, &wptr); - } - statesEP.write(stash, numBytes); -} - // -------------------------------------------------------- 3: Halt -uint32_t haltLightOnTime = 0; - EP_ONDATA_RESPONSES onHaltData(uint8_t* data, uint16_t len){ - axl_halt(); - ERRLIGHT_ON; - haltLightOnTime = millis(); + axl_halt(AXL_HALT_REQUEST); return EP_ONDATA_REJECT; } -Endpoint haltEP(&osap, "halt", onHaltData); - -// -------------------------------------------------------- 4: Moves -> Queue - -EP_ONDATA_RESPONSES onMoveData(uint8_t* data, uint16_t len){ - // this (and states-input) could watch <len> to make sure that - // this code & transmitter code are agreeing on how many DOFs are specd - if(axl_hasQueueSpace()){ - uint16_t rptr = 0; - float rate = ts_readFloat32(data, &rptr); - dofs targ; - for(uint8_t a = 0; a < AXL_NUM_DOF; a ++){ - targ.axis[a] = ts_readFloat32(data, &rptr); - } - axl_addMoveToQueue(targ, rate); - return EP_ONDATA_ACCEPT; - } else { - return EP_ONDATA_WAIT; - } -} - -Endpoint moveEP(&osap, "moves", onMoveData); +Endpoint haltInEP(&osap, "haltInput", onHaltData); +Endpoint haltOutEP(&osap, "haltOutput"); // -------------------------------------------------------- 5: AXL Settings EP_ONDATA_RESPONSES onAXLSettingsData(uint8_t* data, uint16_t len){ // jd, then pairs of accel & vel limits, - float jd; - dofs accelLimits; - dofs velLimits; + axlSettings_t settings; uint16_t rptr = 0; - jd = ts_readFloat32(data, &rptr); for(uint8_t a = 0; a < AXL_NUM_DOF; a ++){ - accelLimits.axis[a] = ts_readFloat32(data, &rptr); - velLimits.axis[a] = ts_readFloat32(data, &rptr); + settings.accelLimits.axis[a] = ts_readFloat32(data, &rptr); + settings.velocityLimits.axis[a] = ts_readFloat32(data, &rptr); } - axl_setJunctionDeviation(jd); - axl_setAccelLimits(accelLimits); - axl_setVelLimits(velLimits); + settings.queueStartDelayMS = ts_readUint32(data, &rptr); + settings.outActuatorID = ts_readUint8(data, &rptr); + // ship em... + axl_setSettings(settings); + // don't stash data, return EP_ONDATA_ACCEPT; } Endpoint axlSettingsEP(&osap, "axlSettings", onAXLSettingsData); +// -------------------------------------------------------- 8: Precalcd-move-adder; + +EP_ONDATA_RESPONSES onPrecalculatedMoveData(uint8_t* data, uint16_t len){ + axlPlannedSegment_t move; + uint16_t rptr = 0; + // location of move-in-sequence, to count continuity, + move.segmentNumber = ts_readUint32(data, &rptr); + // which actuator is requested to ack this mfer, + move.returnActuator = data[rptr ++]; + // unit vector describing move's direction, + for(uint8_t a = 0; a < AXL_NUM_DOF; a ++){ + move.unitVector.axis[a] = ts_readFloat32(data, &rptr); + } + // start vel, accel-rate (up, and down), max velocity, final velocity, distance (all +ve) + move.vi = ts_readFloat32(data, &rptr); + move.accel = ts_readFloat32(data, &rptr); + move.vmax = ts_readFloat32(data, &rptr); + move.vf = ts_readFloat32(data, &rptr); + move.distance = ts_readFloat32(data, &rptr); + // and send it... + axl_addMoveToQueue(move); + // don't write to endpoint... + return EP_ONDATA_REJECT; +} + +Endpoint precalculatedMoveEP(&osap, "plannedMovesIn", onPrecalculatedMoveData); + + // -------------------------------------------------------- 6: Motor Settings uint8_t axisPick = 0; @@ -177,67 +161,9 @@ EP_ONDATA_RESPONSES onMotorSettingsData(uint8_t* data, uint16_t len){ Endpoint motorSettingsEP(&osap, "motorSettings", onMotorSettingsData); -// -------------------------------------------------------- 7: Home Routine - -EP_ONDATA_RESPONSES onHomeData(uint8_t* data, uint16_t len){ - uint16_t rptr = 0; - uint8_t axis = data[rptr ++]; - float rate = ts_readFloat32(data, &rptr); - float offset = ts_readFloat32(data, &rptr); - // alright alright, this would be sliq if we had a little async-cpp api, alas, - if(axl_isMoving()){ - return EP_ONDATA_REJECT; - } else { - axl_home(axis, rate, offset); - return EP_ONDATA_REJECT; - } -} - -#define LIMIT_PIN 23 -#define LIMIT_PORT 0 - -void axl_limitSetup(void){ - PORT->Group[LIMIT_PORT].DIRCLR.reg = (1 << LIMIT_PIN); - PORT->Group[LIMIT_PORT].PINCFG[LIMIT_PIN].bit.INEN = 1; - // pullup - PORT->Group[LIMIT_PORT].OUTSET.reg = (1 << LIMIT_PIN); -} - -boolean axl_checkLimit(void){ - return (PORT->Group[LIMIT_PORT].IN.reg & (1 << LIMIT_PIN)); -} - -Endpoint homeEP(&osap, "home", onHomeData); - -// -------------------------------------------------------- 8: Precalcd-move-adder; - -EP_ONDATA_RESPONSES onPrecalculatedMoveData(uint8_t* data, uint16_t len){ - ERRLIGHT_TOGGLE; - haltLightOnTime = millis() + 250; - move_t move; - // data[0] == AXL_MODE_QUEUE -> I think we designed this serialization so - // that we could hit the same endpoint w/ multiple structures... - uint16_t rptr = 1; - move.vi = ts_readFloat32(data, &rptr); - move.accel = ts_readFloat32(data, &rptr); - move.cruise = ts_readFloat32(data, &rptr); - move.vf = ts_readFloat32(data, &rptr); - move.distance = ts_readFloat32(data, &rptr); - for(uint8_t a = 0; a < AXL_NUM_DOF; a ++){ - move.unitVector[a] = ts_readFloat32(data, &rptr); - move.endPos.axis[a] = ts_readFloat32(data, &rptr); - } - // and send it... - axl_addMoveToQueue(move); - // OSAP::debug("move len " + String(move.distance)); - return EP_ONDATA_REJECT; -} - -Endpoint precalculatedMoveEP(&osap, "precalculatedMoves", onPrecalculatedMoveData); - // -------------------------------------------------------- 9: Limit Halt-Output: -Endpoint limitHaltEP(&osap, "limitOutput"); +// Endpoint limitHaltEP(&osap, "limitOutput"); // -------------------------------------------------------- Arduino Setup @@ -262,49 +188,56 @@ void setup() { uint32_t lastBlink = 0; uint32_t blinkInterval = 50; // ms -uint8_t dummy[128]; - -uint32_t lastLimitCheck = 0; -uint32_t limitCheckInterval = 1; // ms, helps debounce -uint8_t limitStates = 0; -uint32_t errLightOnTime = 0; -boolean errLightOn = false; +uint8_t axlData[256]; +uint16_t axlDataLen = 0; void loop() { osap.loop(); + // check for halt info... + axlDataLen = axl_getHaltPacket(axlData); + if(axlDataLen){ + #warning here - ibid, stick in endpoint, + } + // check for on-queue-completion info... + axlDataLen = axl_getQueueAck(axlData); + if(axlDataLen){ + #warning here - if we have an ack, stick it in the endpoint... + // and if that endpoint isn't clear to write, we're fukd, halt! + // and add an axl_halt(<string>) option to print those messages + } + // refresh stepper hw, stepper_hw->dacRefresh(); - axl_netLoop(dummy); if(lastBlink + blinkInterval < millis()){ lastBlink = millis(); CLKLIGHT_TOGGLE; - updateStatesEP(); + // updateStatesEP(); //axl_printHomeState(); } - // this, i.e, could be on the endpoint's loop code, non? - if(lastLimitCheck + limitCheckInterval < millis()){ - lastLimitCheck = millis(); - // shift left one & tack bit on the end, - limitStates = limitStates << 1; - limitStates |= axl_checkLimit() ? 1 : 0; - // this is the positive-edge mask, - if(limitStates == 0b00001111){ - ERRLIGHT_ON; - errLightOnTime = millis(); - errLightOn = true; - dummy[0] = 1; - limitHaltEP.write(dummy, 1); - } - } - if(errLightOn && errLightOnTime + 250 < millis()){ - ERRLIGHT_OFF; - errLightOn = false; - } + // // this, i.e, could be on the endpoint's loop code, non? + // if(lastLimitCheck + limitCheckInterval < millis()){ + // lastLimitCheck = millis(); + // // shift left one & tack bit on the end, + // limitStates = limitStates << 1; + // limitStates |= axl_checkLimit() ? 1 : 0; + // // this is the positive-edge mask, + // if(limitStates == 0b00001111){ + // ERRLIGHT_ON; + // errLightOnTime = millis(); + // errLightOn = true; + // dummy[0] = 1; + // limitHaltEP.write(dummy, 1); + // } + // } + // if(errLightOn && errLightOnTime + 250 < millis()){ + // ERRLIGHT_OFF; + // errLightOn = false; + // } } // -------------------------------------------------------- Small-Time Ops volatile float stepRatchet = 0.0F; -void axl_onPositionDelta(uint8_t axis, float delta){ +void axl_onPositionDelta(uint8_t axis, float delta, float absolute){ if(axis != axisPick) return; stepRatchet += delta * spu; if(stepRatchet >= 1.0F){ diff --git a/firmware/axl-stepper/src/osape b/firmware/axl-stepper/src/osape index a9c9de9ccddd1eadfe34688fa162999129b0e59b..d523fa272285385edd6f2f9aff1c6abbf5a6d439 160000 --- a/firmware/axl-stepper/src/osape +++ b/firmware/axl-stepper/src/osape @@ -1 +1 @@ -Subproject commit a9c9de9ccddd1eadfe34688fa162999129b0e59b +Subproject commit d523fa272285385edd6f2f9aff1c6abbf5a6d439