X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=ROM2%2Fmotors.c;h=efed7cc73a85255be7cdacc015db394cc2b4c104;hb=f5bc521c83d95d35e852747402a44d1411252c2b;hp=4bb216b273158616e047e2669a4ed9b1f1f2f223;hpb=c99662693a4d79f65d406473647debbd33ec521e;p=uccvend-snackrom.git diff --git a/ROM2/motors.c b/ROM2/motors.c index 4bb216b..efed7cc 100644 --- a/ROM2/motors.c +++ b/ROM2/motors.c @@ -1,50 +1,164 @@ #include "motors.h" #include "vend.h" -void motor_on(u8 slot) { - /* from jump34 */ +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 set_motor(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); +} + +void motor_start() { + bclr_changer_output(A3000_MOTOR_ROW_DISABLE); } -void motors_off() { - bset_changer_output(A3000_MOTOR_ROW_ENABLE); /* XXX active low? */ - delay(10); /* XXX cf motors_off */ +void motor_pause() { + bset_changer_output(A3000_MOTOR_ROW_DISABLE); +} + +void motor_stop() { + bset_changer_output(A3000_MOTOR_ROW_DISABLE); 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) { - int i, c = 0; - motor_on(slot); + u8 i, c = 0; + set_motor(slot); for (i=0; i < 8; i++) { - if (_io_ports[M6811_PORTE] & PORTE_MOTOR_OVERVOLTAGE) { + motor_start(); + delay(5); + if ((_io_ports[M6811_PORTE] & PORTE_MOTOR_OVERVOLTAGE) == 0) { c++; - if (c == 0xff) { - motors_off(); + if (c == 3) { + motor_stop(); return 1; - } else - continue; + } } + motor_pause(); } - motors_off(); + motor_stop(); return 0; } bool is_motor(u8 slot) { - /* FIXME */ - return 1; + /* FIXME - does more need to be done? */ + return motor_here(slot); } -u8 dispense_motor(u8 slot) { - if (!is_motor(slot)) { - return MOTOR_NOSLOT; +bool start_motor(u8 slot) { + u16 i; + u8 r = slot%10; + if (r >= 5) r--; + r = 1 << (r-1); + set_motor(slot); + motor_start(); + delay(50); + for (i = 0; i < 1000; i++) { + if ((home_sensors & r) != 0) return 1; + delay(1); + } + /* it never left */ + motor_stop(); + 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) == 0) return 1; + delay(1); } - motor_on(slot); - /* FIXME */ - return MOTOR_SUCCESS; + /* it never arrived */ + return 0; } -void scan_motors() { - /* FIXME */ +#define is_overcurrent() ((_io_ports[M6811_PORTE] & PORTE_MOTOR_NOT_OVERCURRENT)==0) +bool motor_overcurrent() { + u8 good_passes = 0, t; + for (t = 0; t < 8; t++) { + delay(1); + if (is_overcurrent()) continue; + t = 0; + good_passes++; + if (good_passes == 5) return 0; + } + return 1; +} + +u8 dispense_motor(u8 slot) { + if (!is_motor(slot)) return MOTOR_NOSLOT; + if (!start_motor(slot)) return MOTOR_HOME_FAIL; + delay(100); + + while (1) { + if (motor_overcurrent()) { + motor_stop(); + return MOTOR_CURRENT_FAIL; + } + if (back_home(slot)) { + motor_stop(); + return MOTOR_SUCCESS; + } + } }