Better comments on the stepper motor code

This commit is contained in:
Ivan Izaguirre 2019-12-02 22:43:40 +01:00 committed by Iván Izaguirre
parent 212ed2a90a
commit 9ad13ae483

View File

@ -36,7 +36,7 @@ type cardDisk2Drive struct {
diskette *diskette16sector diskette *diskette16sector
power bool // q4, not realy used for anything power bool // q4, not realy used for anything
position int position int
magnets uint8 // q3, q2, q1 and q0 with q0 on the LSB phases uint8 // q3, q2, q1 and q0 with q0 on the LSB. Magnets that are active on the stepper motor
tracksStep int // Stepmotor for tracks position. 4 steps per track tracksStep int // Stepmotor for tracks position. 4 steps per track
} }
@ -63,8 +63,8 @@ func (c *cardDisk2) assign(a *Apple2, slot int) {
c.addCardSoftSwitchR(phase<<1, func(_ *ioC0Page) uint8 { c.addCardSoftSwitchR(phase<<1, func(_ *ioC0Page) uint8 {
// Update magnets and position // Update magnets and position
drive := &c.drive[c.selected] drive := &c.drive[c.selected]
drive.magnets &^= (1 << phase) drive.phases &^= (1 << phase)
drive.tracksStep = moveStep(drive.magnets, drive.tracksStep) drive.tracksStep = moveStep(drive.phases, drive.tracksStep)
return c.dataLatch // All even addresses return the last dataLatch return c.dataLatch // All even addresses return the last dataLatch
}, fmt.Sprintf("PHASE%vOFF", phase)) }, fmt.Sprintf("PHASE%vOFF", phase))
@ -72,8 +72,8 @@ func (c *cardDisk2) assign(a *Apple2, slot int) {
c.addCardSoftSwitchR((phase<<1)+1, func(_ *ioC0Page) uint8 { c.addCardSoftSwitchR((phase<<1)+1, func(_ *ioC0Page) uint8 {
// Update magnets and position // Update magnets and position
drive := &c.drive[c.selected] drive := &c.drive[c.selected]
drive.magnets |= (1 << phase) drive.phases |= (1 << phase)
drive.tracksStep = moveStep(drive.magnets, drive.tracksStep) drive.tracksStep = moveStep(drive.phases, drive.tracksStep)
return 0 return 0
}, fmt.Sprintf("PHASE%vOFF", phase)) }, fmt.Sprintf("PHASE%vOFF", phase))
@ -119,56 +119,62 @@ func (c *cardDisk2) assign(a *Apple2, slot int) {
c.cardBase.assign(a, slot) c.cardBase.assign(a, slot)
} }
/*
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 (magents): 3 2 1 0 3 2 1 0 3 2 1 0
Cog direction (step withn 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 postion if there is one. Independenly
of the previous position. The previous position is only used to know if it goes up or down
a full group.
*/
const ( const (
maxStep = 68 * 2 // What is the maximum quarter tracks a DiskII can go? undefinedPosition = -1
stepsPerTurn = 8 maxStep = 68 * 2 // What is the maximum quarter tracks a DiskII can go?
) stepsPerGroup = 8
const ( stepsPerTrack = 4
dirN = 0
dirNW = 1
dirW = 2
dirSW = 3
dirS = 4
dirSE = 5
dirE = 6
dirNE = 7
dirUndefined = 8
) )
var magnetsDirections = []int{ var cogPositions = []int{
// Magnets bits, ESWN: east, south, west, north undefinedPosition, // 0000, phases active
dirUndefined, // 0000 0, // 0001
dirN, // 0001 2, // 0010
dirW, // 0010 1, // 0011
dirNW, // 0011 4, // 0100
dirS, // 0100 undefinedPosition, // 0101
dirUndefined, // 0101 3, // 0110
dirSW, // 0110 2, // 0111
dirW, // 0111 6, // 1000
dirE, // 1000 7, // 1001
dirNE, // 1001 undefinedPosition, // 1010
dirUndefined, // 1010 0, // 1011
dirN, // 1011 5, // 1100
dirSE, // 1100 6, // 1101
dirE, // 1101 4, // 1110
dirS, // 1110 undefinedPosition, // 1111
dirUndefined, // 1111
} }
func moveStep(magnets uint8, prevStep int) int { func moveStep(phases uint8, prevStep int) int {
//fmt.Printf("magnets: 0x%x\n", magnets) //fmt.Printf("magnets: 0x%x\n", phases)
magnetsDirection := magnetsDirections[magnets] cogPosition := cogPositions[phases]
if magnetsDirection == dirUndefined { if cogPosition == undefinedPosition {
// Don't move if magnets don't push on a defined direction. // Don't move if magnets don't push on a defined direction.
return prevStep return prevStep
} }
prevDirection := prevStep % stepsPerTurn // Direction, removing full revolutions. prevPosition := prevStep % stepsPerGroup // Direction, step in the current group of magnets.
delta := magnetsDirection - prevDirection delta := cogPosition - prevPosition
if delta < 0 { if delta < 0 {
delta = delta + stepsPerTurn delta = delta + stepsPerGroup
} }
var nextStep int var nextStep int
@ -183,7 +189,7 @@ func moveStep(magnets uint8, prevStep int) int {
nextStep = prevStep nextStep = prevStep
} else { // delta > 4 } else { // delta > 4
// Steps down // Steps down
nextStep = prevStep + delta - stepsPerTurn nextStep = prevStep + delta - stepsPerGroup
if nextStep < 0 { if nextStep < 0 {
nextStep = 0 nextStep = 0
} }
@ -218,10 +224,10 @@ func (c *cardDisk2) processQ6Q7(in uint8) {
} }
if !c.q6 { if !c.q6 {
if !c.q7 { // Q6L-Q7L: Read if !c.q7 { // Q6L-Q7L: Read
track := d.tracksStep / 4 track := d.tracksStep / stepsPerTrack
c.dataLatch, d.position = d.diskette.read(track, d.position) c.dataLatch, d.position = d.diskette.read(track, d.position)
} else { // Q6L-Q7H: Write the dataLatch value to disk. Shift data out } else { // Q6L-Q7H: Write the dataLatch value to disk. Shift data out
track := d.tracksStep / 4 track := d.tracksStep / stepsPerTrack
d.position = d.diskette.write(track, d.position, c.dataLatch) d.position = d.diskette.write(track, d.position, c.dataLatch)
} }
} else { } else {
@ -299,7 +305,7 @@ func (d *cardDisk2Drive) save(w io.Writer) error {
if err != nil { if err != nil {
return err return err
} }
err = binary.Write(w, binary.BigEndian, d.magnets) err = binary.Write(w, binary.BigEndian, d.phases)
if err != nil { if err != nil {
return err return err
} }
@ -319,7 +325,7 @@ func (d *cardDisk2Drive) load(r io.Reader) error {
if err != nil { if err != nil {
return err return err
} }
err = binary.Read(r, binary.BigEndian, &d.magnets) err = binary.Read(r, binary.BigEndian, &d.phases)
if err != nil { if err != nil {
return err return err
} }