Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

kernel/HOLD/dmotor.c

Go to the documentation of this file.
00001 
00006 /*
00007  *  The contents of this file are subject to the Mozilla Public License
00008  *  Version 1.0 (the "License"); you may not use this file except in
00009  *  compliance with the License. You may obtain a copy of the License at
00010  *  http://www.mozilla.org/MPL/
00011  *
00012  *  Software distributed under the License is distributed on an "AS IS"
00013  *  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00014  *  License for the specific language governing rights and limitations
00015  *  under the License.
00016  *
00017  *  The Original Code is legOS code, released October 17, 1999.
00018  *
00019  *  The Initial Developer of the Original Code is Markus L. Noga.
00020  *  Portions created by Markus L. Noga are Copyright (C) 1999
00021  *  Markus L. Noga. All Rights Reserved.
00022  *
00023  *  Contributor(s): Markus L. Noga <markus@noga.de>
00024  *                  Lou Sortman <lou (at) sunsite (dot) unc (dot) edu>
00025  */
00026 
00027 #include <sys/dmotor.h>
00028 #include <dlcd.h>
00029 
00030 #ifdef CONF_DMOTOR
00031 
00032 #include <sys/h8.h>
00033 #include <sys/irq.h>
00034 
00036 //
00037 // Variables
00038 //
00040 
00042 
00045 #ifdef CONF_DMOTOR_HOLD
00046 const unsigned char dm_a_pattern[]={0xc0,0x40,0x80,0x00},
00047                     dm_b_pattern[]={0x0c,0x04,0x08,0x00},
00048                     dm_c_pattern[]={0x03,0x01,0x02,0x00};
00049 #else
00050 const unsigned char dm_a_pattern[]={0x00,0x80,0x40,0xc0},
00051                     dm_b_pattern[]={0x00,0x08,0x04,0x0c},
00052                     dm_c_pattern[]={0x00,0x02,0x01,0x03};
00053 #endif
00054 
00055 MotorState dm_a,                  
00056            dm_b,                  
00057            dm_c;                  
00058 
00059         
00061 //
00062 // Functions
00063 //
00065 
00067 
00069 extern void dm_handler(void);
00070 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00071 __asm__("\n\
00072 .section .text.hi\n\
00073 .align 1\n\
00074 .global _dm_handler\n\
00075 _dm_handler:\n\
00076                 ; r6 saved by ROM\n\
00077                 ; r0 saved by systime_handler\n\
00078 "
00079 #ifdef CONF_DMOTOR_HOLD
00080 "               mov.b #0xcf,r6l                 ; r6l is output\n"
00081 #else
00082 "               sub.w r6,r6                     ; r6l is output\n"
00083 #endif
00084 "               ; we simultaneously load delta (r0h) and sum (r0l)\n\
00085                 ; this depends on byte order, but the H8 will stay MSB\n\
00086                 ; and the resulting code is efficient and compact.\n\
00087                 \n\
00088                 ; motor A\n\
00089                 \n\
00090                 mov.w   @_dm_a,r0\n\
00091                 add.b   #1,r0h                  ; maps 255 to 256\n\
00092                 dec.b   r0h\n\
00093                 addx.b  r0h,r0l                 ; add delta to sum\n\
00094                 bcc     dm0                     ; sum overflow?\n\
00095                   mov.b @_dm_a+2,r6h            ; -> output drive pattern\n\
00096                   xor.b r6h,r6l\n\
00097             dm0:mov.b   r0l,@_dm_a+1            ; save sum\n\
00098 \n\
00099                 ; motor B\n\
00100                 \n\
00101                 mov.w   @_dm_b,r0\n\
00102                 add.b   #1,r0h                  ; maps 255 to 256\n\
00103                 dec.b   r0h\n\
00104                 addx.b  r0h,r0l                 ; add delta to sum\n\
00105                 bcc     dm1                     ; sum overflow?\n\
00106                   mov.b @_dm_b+2,r6h            ; -> output drive pattern\n\
00107                   xor.b r6h,r6l\n\
00108             dm1:mov.b   r0l,@_dm_b+1            ; save sum\n\
00109 \n\
00110                 ; motor C\n\
00111                 \n\
00112                 mov.w   @_dm_c,r0\n\
00113                 add.b   #1,r0h                  ; maps 255 to 256\n\
00114                 dec.b   r0h\n\
00115                 addx.b  r0h,r0l                 ; add delta to sum\n\
00116                 bcc     dm2                     ; sum overflow?\n\
00117                   mov.b @_dm_c+2,r6h            ; -> output drive pattern\n\
00118                   xor.b r6h,r6l\n\
00119             dm2:mov.b   r0l,@_dm_c+1            ; save sum\n\
00120 \n\
00121                 ; driver chip\n\
00122                   \n\
00123                 mov.b   r6l,@_motor_controller:8        ; output motor waveform\n\
00124                 \n\
00125                 rts             \n\
00126         ");
00127 #endif // DOXYGEN_SHOULD_SKIP_THIS
00128         
00129                 
00131 //
00132 void dm_init(void) {
00133   dm_shutdown();                                // shutdown hardware
00134 }
00135 
00136 
00138 //
00139 void dm_shutdown(void) {
00140   motor_a_dir(off);                     // initialize driver data
00141   motor_b_dir(off);
00142   motor_c_dir(off);
00143 
00144   motor_a_speed(MAX_SPEED);
00145   motor_b_speed(MAX_SPEED);
00146   motor_c_speed(MAX_SPEED);
00147 
00148   motor_controller=0x00;                // shutdown hardware
00149 }
00150 
00151 #ifdef CONF_VIS
00152 /*
00153 ** Define non-inline versions to display arrows
00154 */
00155 
00156 void motor_a_dir(MotorDirection dir)
00157 {
00158   dm_a.dir = dm_a_pattern[dir];
00159   dlcd_hide(LCD_A_LEFT);
00160   dlcd_hide(LCD_A_RIGHT);
00161   if (dir == fwd || dir == brake)
00162     dlcd_show(LCD_A_RIGHT);
00163   if (dir == rev || dir == brake)
00164     dlcd_show(LCD_A_LEFT);
00165 }
00166 
00167 void motor_b_dir(MotorDirection dir)
00168 {
00169   dm_b.dir = dm_b_pattern[dir];
00170   dlcd_hide(LCD_B_LEFT);
00171   dlcd_hide(LCD_B_RIGHT);
00172   if (dir == fwd || dir == brake)
00173     dlcd_show(LCD_B_RIGHT);
00174   if (dir == rev || dir == brake)
00175     dlcd_show(LCD_B_LEFT);
00176 }
00177 
00178 void motor_c_dir(MotorDirection dir)
00179 {
00180   dm_c.dir = dm_c_pattern[dir];
00181   dlcd_hide(LCD_C_LEFT);
00182   dlcd_hide(LCD_C_RIGHT);
00183   if (dir == fwd || dir == brake)
00184     dlcd_show(LCD_C_RIGHT);
00185   if (dir == rev || dir == brake)
00186     dlcd_show(LCD_C_LEFT);
00187 }
00188 
00189 #endif // ifdef CONF_VIS
00190 
00192 
00194 void motor_a_speed(unsigned char speed)
00195 {
00196   dm_a.access.c.delta = speed;
00197 }
00198 
00200 
00202 void motor_b_speed(unsigned char speed)
00203 {
00204   dm_b.access.c.delta = speed;
00205 }
00206 
00208 
00210 void motor_c_speed(unsigned char speed)
00211 {
00212   dm_c.access.c.delta = speed;
00213 }
00214 
00215 #endif // CONF_DMOTOR

brickOS is released under the Mozilla Public License.
Original code copyright 1998-2002 by the authors.

Generated on Mon Feb 16 21:02:10 2004 for brickOS Kernel Developer by doxygen 1.3.5