brickOS Kernel Developer v0.9.0
dmotor.c
Go to the documentation of this file.
1
6/*
7 * The contents of this file are subject to the Mozilla Public License
8 * Version 1.0 (the "License"); you may not use this file except in
9 * compliance with the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
11 *
12 * Software distributed under the License is distributed on an "AS IS"
13 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
14 * License for the specific language governing rights and limitations
15 * under the License.
16 *
17 * The Original Code is legOS code, released October 17, 1999.
18 *
19 * The Initial Developer of the Original Code is Markus L. Noga.
20 * Portions created by Markus L. Noga are Copyright (C) 1999
21 * Markus L. Noga. All Rights Reserved.
22 *
23 * Contributor(s): Markus L. Noga <markus@noga.de>
24 * Lou Sortman <lou (at) sunsite (dot) unc (dot) edu>
25 */
26
27#include <sys/dmotor.h>
28#include <dlcd.h>
29
30#ifdef CONF_DMOTOR
31
32#include <sys/h8.h>
33#include <sys/irq.h>
34
36//
37// Variables
38//
40
42
45#ifdef CONF_DMOTOR_HOLD
46const unsigned char dm_a_pattern[]={0xc0,0x40,0x80,0x00},
47 dm_b_pattern[]={0x0c,0x04,0x08,0x00},
48 dm_c_pattern[]={0x03,0x01,0x02,0x00};
49#else
50const unsigned char dm_a_pattern[]={0x00,0x80,0x40,0xc0},
51 dm_b_pattern[]={0x00,0x08,0x04,0x0c},
52 dm_c_pattern[]={0x00,0x02,0x01,0x03};
53#endif
54
56 dm_b,
57 dm_c;
58
59
61//
62// Functions
63//
65
67
69extern void dm_handler(void);
70#ifndef DOXYGEN_SHOULD_SKIP_THIS
71__asm__("\n\
72.section .text.hi\n\
73.align 1\n\
74.global _dm_handler\n\
75_dm_handler:\n\
76 ; r6 saved by ROM\n\
77 ; r0 saved by systime_handler\n\
78"
79#ifdef CONF_DMOTOR_HOLD
80" mov.b #0xcf,r6l ; r6l is output\n"
81#else
82" sub.w r6,r6 ; r6l is output\n"
83#endif
84" ; we simultaneously load delta (r0h) and sum (r0l)\n\
85 ; this depends on byte order, but the H8 will stay MSB\n\
86 ; and the resulting code is efficient and compact.\n\
87 \n\
88 ; motor A\n\
89 \n\
90 mov.w @_dm_a,r0\n\
91 add.b #1,r0h ; maps 255 to 256\n\
92 dec.b r0h\n\
93 addx.b r0h,r0l ; add delta to sum\n\
94 bcc dm0 ; sum overflow?\n\
95 mov.b @_dm_a+2,r6h ; -> output drive pattern\n\
96 xor.b r6h,r6l\n\
97 dm0:mov.b r0l,@_dm_a+1 ; save sum\n\
98\n\
99 ; motor B\n\
100 \n\
101 mov.w @_dm_b,r0\n\
102 add.b #1,r0h ; maps 255 to 256\n\
103 dec.b r0h\n\
104 addx.b r0h,r0l ; add delta to sum\n\
105 bcc dm1 ; sum overflow?\n\
106 mov.b @_dm_b+2,r6h ; -> output drive pattern\n\
107 xor.b r6h,r6l\n\
108 dm1:mov.b r0l,@_dm_b+1 ; save sum\n\
109\n\
110 ; motor C\n\
111 \n\
112 mov.w @_dm_c,r0\n\
113 add.b #1,r0h ; maps 255 to 256\n\
114 dec.b r0h\n\
115 addx.b r0h,r0l ; add delta to sum\n\
116 bcc dm2 ; sum overflow?\n\
117 mov.b @_dm_c+2,r6h ; -> output drive pattern\n\
118 xor.b r6h,r6l\n\
119 dm2:mov.b r0l,@_dm_c+1 ; save sum\n\
120\n\
121 ; driver chip\n\
122 \n\
123 mov.b r6l,@_motor_controller:8 ; output motor waveform\n\
124 \n\
125 rts \n\
126 ");
127#endif // DOXYGEN_SHOULD_SKIP_THIS
128
129
131//
132void dm_init(void) {
133 dm_shutdown(); // shutdown hardware
134}
135
136
138//
139void dm_shutdown(void) {
140 motor_a_dir(off); // initialize driver data
143
147
148 motor_controller=0x00; // shutdown hardware
149}
150
151#ifdef CONF_VIS
152/*
153** Define non-inline versions to display arrows
154*/
155
157{
158 dm_a.dir = dm_a_pattern[dir];
161 if (dir == fwd || dir == brake)
163 if (dir == rev || dir == brake)
165}
166
168{
169 dm_b.dir = dm_b_pattern[dir];
172 if (dir == fwd || dir == brake)
174 if (dir == rev || dir == brake)
176}
177
179{
180 dm_c.dir = dm_c_pattern[dir];
183 if (dir == fwd || dir == brake)
185 if (dir == rev || dir == brake)
187}
188
189#endif // ifdef CONF_VIS
190
191#endif // CONF_DMOTOR
__asm__("\n\ .text\n\ .globl _atomic_inc\n\ _atomic_inc:\n\ stc ccr, r1h ; save flags\n\ orc #0x80, ccr ; disable all but NMI\n\ mov.b @r0, r1l\n\ inc r1l\n\ mov.b r1l, @r0\n\ ldc r1h, ccr ; restore flags\n\ rts\n\ ")
Interface: direct control of LCD display.
#define LCD_C_LEFT
Definition dlcd.h:120
#define LCD_B_RIGHT
Definition dlcd.h:117
#define dlcd_hide(a)
clear a segment directly in the LCD buffer
Definition dlcd.h:180
#define LCD_A_RIGHT
Definition dlcd.h:113
#define dlcd_show(a)
set a segment directly in the LCD buffer
Definition dlcd.h:175
#define LCD_C_RIGHT
Definition dlcd.h:121
#define LCD_B_LEFT
Definition dlcd.h:116
#define LCD_A_LEFT
Definition dlcd.h:112
const unsigned char dm_a_pattern[4]
motor drive patterns
void motor_c_speed(unsigned char speed)
set motor C speed
Definition dmotor.h:159
void motor_b_speed(unsigned char speed)
set motor B speed
Definition dmotor.h:151
MotorState dm_b
motor B state
Definition dmotor.h:89
const unsigned char dm_b_pattern[4]
Definition dmotor.h:85
MotorState dm_a
motor A state
void motor_b_dir(MotorDirection dir)
set motor B direction to dir
const unsigned char dm_c_pattern[4]
Definition dmotor.h:86
MotorState dm_c
motor C state
Definition dmotor.h:90
MotorDirection
the motor directions
Definition dmotor.h:44
@ fwd
forward
Definition dmotor.h:46
@ rev
reverse
Definition dmotor.h:47
@ brake
hold current position
Definition dmotor.h:48
@ off
freewheel
Definition dmotor.h:45
void motor_a_dir(MotorDirection dir)
set motor A direction to dir
void motor_c_dir(MotorDirection dir)
set motor C direction to dir
#define MAX_SPEED
maximum motor speed
Definition dmotor.h:72
void motor_a_speed(unsigned char speed)
set motor A speed
Definition dmotor.h:143
Internal Interface: H8/3297 processor registers.
Internal LNP Interface: RCX redirected IRQ vectors.
the motor status type.
Definition dmotor.h:54
unsigned char dir
output pattern when sum overflows
Definition dmotor.h:66
Internal Interface: direct motor control.
void dm_init(void)
initialize motors
void dm_shutdown(void)
shutdown motors
unsigned char motor_controller
RCX Motor Controller port.