Select Git revision
fab-step-log.md NaN GiB
## Log
## 2020 11 05
Started in, have the schematic mostly roughed out: this'll be 1.5 sided (solid GND below a routed layer). I think... the largest challenge is just getting things around themselves without using any vias. Found a tranciever as well.
## 2020 11 16
Just routed out the program / power / data interface side of this.

Success going forward will rely on a a fortuitous alignment of the RS485 interface pins against a SERCOM port somewhere on 11-16... not at all sure if any such alignment exists.
## 2020 11 17
Lucky me, those line up. I can put the SERCOM's TXPO at 0 (for TX on SER-0) and and RXPO at 3 (for RX on SER-3) and the middle two will do data enable and rx enable, just GPIO.

So, sorted that out. I think it works OK. I can make one of these in the fab-version, and can copy the schematic onto a smaller 2-layer board to fab lots of at a board house, having pins 17-20 free for an AS5047 on the back... same RS485 interface, maybe the QFN D21, and 0805s or smaller passives, pinch traces / spaces etc.
## 2021 06 12
Re-routed this for UCBus compatibility, still looks like the best option despite SPI availability: SPI interrupt handlers are minimum ~ 2us, meaning byte period of 2.6us (at 3MHz) is limiting, might as well use simplicity of UART, and ability / option for it to self-configure as P2P connection, etc. RS485 UART is same pin count as TTL SPI, would rather have noise / distance immunity.
I left off some pins (SERCOM0) to potentially add an encoder here, the routing for that would be tough but probably possible.


## 2021 06 19
Realized today that I had 5v, 24v lines on the plug optimistically configured for easier routing: the cable symmetry results in a more awkward routing which I've corrected, just had to squish the connector / RS485 bit up 1.5mm or so, so that I could wiggle those 5v and 24v lines beneath the connector:


## 2022 01 10
Back here but I am not working on the closed-loop version now... need to split these repos... writing code for the actually-fab-abble version.
I think I'm just going to get right into a step-tick rather than float-tick operation.
Though this means some re-work at the head first.
It's totally easy though, I write a little step mask in the motor interface class, get that on interrupt - I am even caching two so that I can get the full 10kHz rather than 5.
I think I need a config / setup on the js side.
OK this is almost jogging - I need some motor config, then I think I actually have some driver level debug to do, not unlikely with the VREF stuff.
### H-Bridge : Code Alignment
It has come to my attention that I changed the pins on all of these things, and hadn't re-written to use the timer-counter rc filters, whoops.
Looking a lot better now that I sorted that haha - looks like I still need to scope the pwm'd lines, I am maybe flipping a phase improperly.

Yeah, something like that: microsteps increment *back* but flipping ticks *forwards* so I'm somehow misaligned.
had an 'a' where a 'b' was meant to be.
Now I'm just not seeing it hold while it's microstepping...
OK it's all up, and jogs around w/ the motion system, rad.
### Homing Routine
Next thing I need is a little homing routine... I think I will do `homingRate` in steps / second... rather than keep any other info in the motor.
This is still kind of a pain.
Great, homing works. It's stateful, that's why it's such a pain - and has to work all asynchronously;
```cpp
#include "homing.h"
#include "drivers/step_a4950.h"
endpoint_t* _homeStateEP;
uint8_t homeState = HOMESTATE_NONE;
uint32_t homeBackoffStepsTaken = 0;
// home settings
boolean homeDir = true;
unsigned long lastHomeOperation = 0;
unsigned long homeOperationPeriod = 1000; // in us
uint32_t homeBackoffDistance = 100;
void homeSetup(endpoint_t* homeStateEP){
// stash this
_homeStateEP = homeStateEP;
// make an input
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);
}
// return true if limit switch is hit
boolean limitHit(void){
return (PORT->Group[LIMIT_PORT].IN.reg & (1 << LIMIT_PIN));
}
void writeHomeSettings(boolean dir, uint32_t stepsPerSecond, uint32_t offset){
homeDir = dir;
homeOperationPeriod = 1000000 / stepsPerSecond;
homeBackoffDistance = offset;
}
uint8_t getHomeState(void){
return homeState;
}
void startHomingRoutine(void){
homeState = HOMESTATE_APPROACH;
endpointWrite(_homeStateEP, &homeState, 1);
}
void runHomingRoutine(void){
// run this at a rate...
if(lastHomeOperation + homeOperationPeriod > micros()) return;
lastHomeOperation = micros();
// state switch;
switch(homeState){
case HOMESTATE_NONE:
break;
case HOMESTATE_APPROACH:
// check for contact,
if(limitHit()){
homeState = HOMESTATE_BACKOFF;
endpointWrite(_homeStateEP, &homeState, 1);
homeBackoffStepsTaken = 0;
} else {
step_a4950_dir(homeDir);
step_a4950_step();
}
break;
case HOMESTATE_BACKOFF:
step_a4950_dir(!homeDir);
step_a4950_step();
homeBackoffStepsTaken ++;
if(homeBackoffStepsTaken > homeBackoffDistance){
homeState = HOMESTATE_NONE;
endpointWrite(_homeStateEP, &homeState, 1);
}
break;
default:
// broken,
homeState = HOMESTATE_NONE;
endpointWrite(_homeStateEP, &homeState, 1);
break;
}
}
```
Now I just want to touch up the motor APIs in JS, and add the steps-per-unit adjust stuff in the motion-head, etc... I should be pretty close now.
### Power State API
Just a bunch of buttons, turns out to not be so bad. Done.
### New Motor API and JS Config
This should actually be chill... it's working after all, right?
I'm setting the SPUs in the motion-head now... meaning I could also calculate / guard against max rates there.
- motion-head things
- steps per unit
- max accels
- max rates
- motor things
- direction inversion
- microstepping
- axis picking
OK I've diffed all that... need to make a microstep update actually do something, then this adventure is over.
11752 / 24584
12520 / 24976
Done, for the time being. Probably needs in-mcu guards against large rates.