X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=ROM2%2Fmotors.c;h=64158ae56ab5e22b99ca93aae1123661cea2336f;hb=deac3b8b66af0f499d6da73cf5bf8479c7d9fad9;hp=80a11a76d6b75cd4b4f61e4471986783c15b1097;hpb=4f35424978e202fff48c2331eee9fd01e3da244f;p=uccvend-snackrom.git diff --git a/ROM2/motors.c b/ROM2/motors.c index 80a11a7..64158ae 100644 --- a/ROM2/motors.c +++ b/ROM2/motors.c @@ -1,2 +1,158 @@ +#include "motors.h" #include "vend.h" +const u8 motor_lookup[80] = +{ 1,12,23,34,46,57,68,79, + 11,22,33,44,56,67,78,89, + 21,32,43,54,66,77,88,99, + 31,42,53,64,76,87,98, + 9,41,52,63,74,86,97, + 8,19,51,62,73,84,96, + 7,18,29,61,72,83,94, + 6,17,28,39,71,82,93, + 4,16,27,38,49,81,92, + 3,14,26,37,48,59,91, + 2,13,24,36,47,58,69, +}; + +void motor_shift_send(u8 data) { + u8 i; + /* load it in, MSB first */ + for (i = 0; i < 8; i++) { + if (data & 0x80) + bset_misc_output(A3800_MOTOR_DATA); + else + bclr_misc_output(A3800_MOTOR_DATA); + + delay(1); + + /* clock pulse */ + bset((void*)&_io_ports[M6811_PORTA], PORTA_MOTOR_CLOCK); + delay(1); + bclr((void*)&_io_ports[M6811_PORTA], PORTA_MOTOR_CLOCK); + delay(1); + + data = data << 1; + } +} + +void motor_on(u8 slot) { + u8 row, col; + row = slot%10; + col = slot/10; + if (row >= 5) row--; + + /* loads up the shift register with the right bits */ + bclr_misc_output(A3800_MOTOR_COL8_ENABLE|A3800_MOTOR_COL9_ENABLE); + switch (col) { + case 8: + bset_misc_output(A3800_MOTOR_COL8_ENABLE); + motor_shift_send(0); + break; + case 9: + bset_misc_output(A3800_MOTOR_COL9_ENABLE); + motor_shift_send(0); + break; + default: /* < 8 */ + motor_shift_send(1 << col); /* cols from 0..7 */ + bclr((void*)&_io_ports[M6811_PORTA], PORTA_MOTOR_COL_DISABLE); + } + + motor_shift_send(1 << (row-1)); /* rows from 1..8 here */ + + bclr((void*)&_io_ports[M6811_PORTA], PORTA_MOTOR_CLOCK); + bclr_changer_output(A3000_MOTOR_ROW_DISABLE); +} + +void motors_off() { + bset_changer_output(A3000_MOTOR_ROW_DISABLE); + delay(10); /* XXX cf motors_off */ + bset((void*)&_io_ports[M6811_PORTA], PORTA_MOTOR_COL_DISABLE); + bclr_misc_output(A3800_MOTOR_COL8_ENABLE | A3800_MOTOR_COL9_ENABLE); +} + +bool motor_here(u8 slot) { + u8 i, c = 0; + motor_on(slot); + for (i=0; i < 8; i++) { + delay(5); + if (_io_ports[M6811_PORTE] & PORTE_MOTOR_OVERVOLTAGE) { + c++; + if (c == 0xff) { + motors_off(); + return 1; + } else + continue; + } + } + motors_off(); + return 0; +} + +bool is_motor(u8 slot) { + /* FIXME - does more need to be done? */ + return motor_here(slot); +} + +bool left_home(u8 slot) { + u8 i, r = slot%10; + if (r >= 5) r--; + r = 1 << (r-1); + + for (i = 0; i < 5; i++) + if ((home_sensors & r) == 0) return 1; + + /* it never left */ + return 0; +} + +bool back_home(u8 slot) { + u8 i, r = slot%10; + if (r >= 5) r--; + r = 1 << (r-1); + + for (i = 0; i < 5; i++) { + if (home_sensors & r) return 1; + if ((_io_ports[M6811_PORTE] & PORTE_MOTOR_OVERCURRENT) == 0) return 1; + } + + /* it never left */ + return 0; +} + +bool motor_overcurrent() { + u8 t = 0, i = 0; + while(1) { + t++; + if (7 == t) return 1; + if (_io_ports[M6811_PORTE] & PORTE_MOTOR_OVERCURRENT) continue; + t = 0; + i++; + if (5 == i) return 0; + } +} + +u8 dispense_motor(u8 slot) { + //if (!is_motor(slot)) return MOTOR_NOSLOT; + + motor_on(slot); + delay(100); + + if (!left_home(slot)) { + motors_off(); + return MOTOR_HOME_FAIL; + } + + while (1) { + if (motor_overcurrent()) { + motors_off(); + return MOTOR_CURRENT_FAIL; + } + /* something should call motor_here? */ + if (back_home(slot)) { + motors_off(); + return MOTOR_SUCCESS; + } + } +} +