mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-28 02:30:36 +00:00
84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
package izapple2
|
|
|
|
/*
|
|
Stepper motor to position the track.
|
|
|
|
There are a number of group of four magnets. The stepper motor can be thought as a long
|
|
line of groups of magnets, each group on the same configuration. We call phase each of those
|
|
magnets. The cog is attracted to the enabled magnets, and can stay aligned to a magnet or
|
|
between two.
|
|
|
|
Phases (magnets): 3 2 1 0 3 2 1 0 3 2 1 0
|
|
Cog direction (step within a group): 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
|
|
|
We will consider that the cog would go to the prefferred position if there is one. Independently
|
|
of the previous position. The previous position is only used to know if it goes up or down
|
|
a full group.
|
|
|
|
Phases are coded in 4 bits in an uint8. Q3, q2, q1 and q0 with q0 on the LSB.
|
|
*/
|
|
|
|
const (
|
|
undefinedPosition = -1
|
|
maxStep = 68 * 2 // What is the maximum quarter tracks a DiskII can go?
|
|
stepsPerGroup = 8
|
|
stepsPerTrack = 4
|
|
)
|
|
|
|
var cogPositions = []int{
|
|
undefinedPosition, // 0000, phases active
|
|
0, // 0001
|
|
2, // 0010
|
|
1, // 0011
|
|
4, // 0100
|
|
undefinedPosition, // 0101
|
|
3, // 0110
|
|
2, // 0111
|
|
6, // 1000
|
|
7, // 1001
|
|
undefinedPosition, // 1010
|
|
0, // 1011
|
|
5, // 1100
|
|
6, // 1101
|
|
4, // 1110
|
|
undefinedPosition, // 1111
|
|
}
|
|
|
|
func moveDriveStepper(phases uint8, prevStep int) int {
|
|
|
|
//fmt.Printf("magnets: 0x%x\n", phases)
|
|
|
|
cogPosition := cogPositions[phases]
|
|
if cogPosition == undefinedPosition {
|
|
// Don't move if magnets don't push on a defined direction.
|
|
return prevStep
|
|
}
|
|
|
|
prevPosition := prevStep % stepsPerGroup // Direction, step in the current group of magnets.
|
|
delta := cogPosition - prevPosition
|
|
if delta < 0 {
|
|
delta = delta + stepsPerGroup
|
|
}
|
|
|
|
var nextStep int
|
|
if delta < 4 {
|
|
// Steps up
|
|
nextStep = prevStep + delta
|
|
if nextStep > maxStep {
|
|
nextStep = maxStep
|
|
}
|
|
} else if delta == 4 {
|
|
// Don't move if magnets push on the opposite direction
|
|
nextStep = prevStep
|
|
} else { // delta > 4
|
|
// Steps down
|
|
nextStep = prevStep + delta - stepsPerGroup
|
|
if nextStep < 0 {
|
|
nextStep = 0
|
|
}
|
|
}
|
|
|
|
//fmt.Printf("[DiskII] 1/4 track: %03d %vO\n", nextStep, strings.Repeat(" ", nextStep))
|
|
return nextStep
|
|
}
|