Imported Upstream version 2.9.0
[debian/cc1111] / device / examples / startupcode / src / cpu_c515a.c
1 /********************************************************************/
2 /* Function    : Siemens CPU C515A-L24M dependinge Functions   FILE */
3 /*------------------------------------------------------------------*/
4 /* Description : All CPU dependig functions like UART fe. are       */
5 /*               are initialized here                               */
6 /*------------------------------------------------------------------*/
7 /* Author      : Michael Schmitt                                    */
8 /*------------------------------------------------------------------*/
9 /* Input       : none                                               */
10 /*------------------------------------------------------------------*/
11 /* Returnvalue : none                                               */
12 /*------------------------------------------------------------------*/
13 /* History     : 00/03    V1.0 Initial Version                      */
14 /*                                                                  */
15 /********************************************************************/
16 #ifndef __FILE_CPU_C515A
17 #define __FILE_CPU_C515A
18
19 // All that has to be included and / or defined is done here
20
21 #include "../inc/hardware_description.h"
22
23 // END INCLUDES & DEFINES ===========================================
24
25 /********************************************************************/
26 /* Function    : CpuIdle()                                      SUB */
27 /*------------------------------------------------------------------*/
28 /* Description : If no CPU Power is need, we put into idle mode     */
29 /*------------------------------------------------------------------*/
30 /* Author      : Michael Schmitt                                    */
31 /*------------------------------------------------------------------*/
32 /* Input       : none                                               */
33 /*------------------------------------------------------------------*/
34 /* Returnvalue : none                                               */
35 /*------------------------------------------------------------------*/
36 /* History     : 00/03    V1.0 Initial Version                      */
37 /*                                                                  */
38 /********************************************************************/
39
40 void CpuIdle()
41 {
42     // The Siemens Manual says, that we have to wait until the AD-Conversion
43     // is completed before we put the cpu into idle mode
44
45     // wait until AD-Conversion is finished
46     while( BSY )
47     {
48         //
49     }
50
51
52     CPUIDLE = 1;
53 #ifdef USE_SYSTEM_TIMER
54     PCON |= 0x01; // IDL-Bit in register PCON starts IDLE Mode
55     PCON |= 0x20; //
56 #else
57     // If there is no regular INT source, we better do not use
58     // the IDLE Mode
59     NOP;
60 #endif
61     CPUIDLE = 0;
62 }
63
64 /********************************************************************/
65 /* Function    : WatchDog()                                     SUB */
66 /*------------------------------------------------------------------*/
67 /* Description : Internal (and external) Watchdogs trigger          */
68 /*------------------------------------------------------------------*/
69 /* Author      : Michael Schmitt                                    */
70 /*------------------------------------------------------------------*/
71 /* Input       : none                                               */
72 /*------------------------------------------------------------------*/
73 /* Returnvalue : none                                               */
74 /*------------------------------------------------------------------*/
75 /* History     : 00/03    V1.0 Initial Version                      */
76 /*                                                                  */
77 /********************************************************************/
78
79 void WatchDog( void )
80 {
81     //NOP;
82     // retrigger Externer Watchdog
83     // Interner Watchdog not yet implemented
84 }
85
86
87 // ===========================================================================
88 // Serial IO with the internal UART in Interrupt Mode
89 #ifdef SERIAL_VIA_INTERRUPT
90
91 #define SERIAL_IS_DEFINED
92
93 // Transmit Buffersize
94 #ifndef SERIAL_VIA_INTERRUPT_XBUFLEN
95 #error "SERIAL_VIA_INTERRUPT_XBUFLEN not defined using default size 8"
96 #define SERIAL_VIA_INTERRUPT_XBUFLEN 8
97 #endif
98
99 // Receive Buffersize
100 #ifndef SERIAL_VIA_INTERRUPT_RBUFLEN
101 #error "SERIAL_VIA_INTERRUPT_RBUFLEN not defined using default size 8"
102 #define SERIAL_VIA_INTERRUPT_RBUFLEN 8
103 #endif
104
105 // in interrupt mode the ing buffer is placed in XDATA memory
106 volatile xdata static unsigned char SERIAL_VIA_INTERRUPT_RBUF[SERIAL_VIA_INTERRUPT_RBUFLEN];
107 volatile xdata static unsigned char SERIAL_VIA_INTERRUPT_XBUF[SERIAL_VIA_INTERRUPT_XBUFLEN];
108 volatile xdata static unsigned char SERIAL_VIA_INTERRUPT_RCNT;
109 volatile xdata static unsigned char SERIAL_VIA_INTERRUPT_XCNT;
110 volatile xdata static unsigned char SERIAL_VIA_INTERRUPT_RPOS;
111 volatile xdata static unsigned char SERIAL_VIA_INTERRUPT_XPOS;
112 volatile xdata static unsigned char SERIAL_VIA_INTERRUPT_BUSY;
113
114 #endif // SERIAL_VIA_INTERRUPT
115
116 // ===========================================================================
117 // Serial IO with them internal UART in Polling Mode
118 #ifdef SERIAL_VIA_POLLING
119 #define SERIAL_IS_DEFINED
120 #endif // SERIAL_VIA_POLLING
121
122 #ifdef SERIAL_IS_DEFINED
123 // calculate the reloadvalues acc. to the definitions
124 #ifndef CPUCLKHZ
125 #error "CPUCLKHZ not defined !"
126 #endif
127 #ifndef BAUDRATE
128 #error "BAUDRATE not defined !"
129 #endif
130 // The Siemens CPU C515A has a build in Baudrategenerator, therefore we use it instead
131 // of timer 1 this gives a better resolution
132
133 #define BAUDRATEGENRELOADVALUE (1024-(2*CPUCLKHZ/64/BAUDRATE))
134 #define TIMER1MODE2RELOADVALUE  (256-(2*CPUCLKHZ/32/12/BAUDRATE))
135
136 #endif // SERIAL_IS_DEFINED
137
138 // ===========================================================================
139 // now to the serial functions
140 #ifdef SERIAL_VIA_INTERRUPT
141 /********************************************************************/
142 /* Function    : SERIAL_VIA_INTERRUPT()                         ISR */
143 /*------------------------------------------------------------------*/
144 /* Description : If a serial INT occours, the sub function is called*/
145 /*               if a char is not yet transmitted, it is stored in  */
146 /*               the uart and transmitted, if a char has been       */
147 /*               received, it will be placed in the rx-buffer
148 /*------------------------------------------------------------------*/
149 /* Author      : Michael Schmitt                                    */
150 /*------------------------------------------------------------------*/
151 /* Input       : none                                               */
152 /*------------------------------------------------------------------*/
153 /* Returnvalue : none                                               */
154 /*------------------------------------------------------------------*/
155 /* History     : 00/03    V1.0 Initial Version                      */
156 /*                                                                  */
157 /********************************************************************/
158 void SERIALVIAINTERRUPT (void) interrupt SI0_VECTOR
159 {
160     if (RI)
161     {
162         RI = 0;
163         // char that are already inside the buffer should not be overwritten
164         if (SERIAL_VIA_INTERRUPT_RCNT < SERIAL_VIA_INTERRUPT_RBUFLEN)
165         {
166             SERIAL_VIA_INTERRUPT_RBUF [(SERIAL_VIA_INTERRUPT_RPOS+SERIAL_VIA_INTERRUPT_RCNT++) % SERIAL_VIA_INTERRUPT_RBUFLEN] = SBUF;
167         }
168    }
169    if (TI)
170    {
171        TI = 0;
172        if (SERIAL_VIA_INTERRUPT_BUSY = SERIAL_VIA_INTERRUPT_XCNT)
173        {   /* Assignment, _not_ comparison! */
174            SERIAL_VIA_INTERRUPT_XCNT--;
175            SBUF = SERIAL_VIA_INTERRUPT_XBUF [SERIAL_VIA_INTERRUPT_XPOS++];
176            if (SERIAL_VIA_INTERRUPT_XPOS >= SERIAL_VIA_INTERRUPT_XBUFLEN)
177            {
178                SERIAL_VIA_INTERRUPT_XPOS = 0;
179            }
180        }
181    }
182 }
183
184 /********************************************************************/
185 /* Function    : putchar()                                      SUB */
186 /*------------------------------------------------------------------*/
187 /* Description : everybody knows what this function is doing        */
188 /*------------------------------------------------------------------*/
189 /* Author      : Michael Schmitt                                    */
190 /*------------------------------------------------------------------*/
191 /* Input       : char Byte                                          */
192 /*------------------------------------------------------------------*/
193 /* Returnvalue : none                                               */
194 /*------------------------------------------------------------------*/
195 /* History     : 00/03    V1.0 Initial Version                      */
196 /*                                                                  */
197 /********************************************************************/
198 void putchar(  char Byte )
199 {
200     while (SERIAL_VIA_INTERRUPT_XCNT >= SERIAL_VIA_INTERRUPT_XBUFLEN)
201     {
202         // buffer is full, wait until room
203         WatchDog();
204         CpuIdle();
205     }
206     ES = 0;
207
208     if (SERIAL_VIA_INTERRUPT_BUSY)
209     {
210         SERIAL_VIA_INTERRUPT_XBUF[(SERIAL_VIA_INTERRUPT_XPOS+SERIAL_VIA_INTERRUPT_XCNT++) % SERIAL_VIA_INTERRUPT_XBUFLEN] = Byte;
211     }
212     else
213     {
214         SBUF = Byte;
215         SERIAL_VIA_INTERRUPT_BUSY = 1;
216     }
217     ES = 1;
218 }
219
220 /********************************************************************/
221 /* Function    : getchar()                                      SUB */
222 /*------------------------------------------------------------------*/
223 /* Description : everybody knows what this function is doing        */
224 /*------------------------------------------------------------------*/
225 /* Author      : Michael Schmitt                                    */
226 /*------------------------------------------------------------------*/
227 /* Input       : none                                               */
228 /*------------------------------------------------------------------*/
229 /* Returnvalue : char Byte                                          */
230 /*------------------------------------------------------------------*/
231 /* History     : 00/03    V1.0 Initial Version                      */
232 /*                                                                  */
233 /********************************************************************/
234 char getchar( void )
235 {
236     unsigned char c;
237     while (!SERIAL_VIA_INTERRUPT_RCNT)
238     {
239         // no char avail, so wait
240         WatchDog();
241         CpuIdle();
242     }
243     ES = 0;
244     SERIAL_VIA_INTERRUPT_RCNT--;
245     c = SERIAL_VIA_INTERRUPT_RBUF [SERIAL_VIA_INTERRUPT_RPOS++];
246     if (SERIAL_VIA_INTERRUPT_RPOS >= SERIAL_VIA_INTERRUPT_RBUFLEN)
247     {
248         SERIAL_VIA_INTERRUPT_RPOS = 0;
249
250     }
251     ES = 1;
252     return (c);
253 }
254
255 /********************************************************************/
256 /* Function    : keypressed()                                   SUB */
257 /*------------------------------------------------------------------*/
258 /* Description : checks, if a char is available                     */
259 /*------------------------------------------------------------------*/
260 /* Author      : Michael Schmitt                                    */
261 /*------------------------------------------------------------------*/
262 /* Input       : none                                               */
263 /*------------------------------------------------------------------*/
264 /* Returnvalue : TRUE yes, FALSE no                                 */
265 /*------------------------------------------------------------------*/
266 /* History     : 00/03    V1.0 Initial Version                      */
267 /*                                                                  */
268 /********************************************************************/
269 char keypressed( void )
270 {
271     unsigned char c;
272
273     if(SERIAL_VIA_INTERRUPT_RCNT)
274     {
275         c = TRUE;
276     }
277     else
278     {
279         c = FALSE;
280     }
281     return (c);
282 }
283
284 #endif
285
286 // ===========================================================================
287 // Now the Internal UART Handling if Polling Method is used
288 #ifdef SERIAL_VIA_POLLING
289 /********************************************************************/
290 /* Function    : putchar()                                      SUB */
291 /*------------------------------------------------------------------*/
292 /* Description : everybody knows what this function is doing        */
293 /*------------------------------------------------------------------*/
294 /* Author      : Michael Schmitt                                    */
295 /*------------------------------------------------------------------*/
296 /* Input       : char Byte                                          */
297 /*------------------------------------------------------------------*/
298 /* Returnvalue : none                                               */
299 /*------------------------------------------------------------------*/
300 /* History     : 00/03    V1.0 Initial Version                      */
301 /*                                                                  */
302 /********************************************************************/
303 void putchar(  char Byte )
304 {
305     while( !TI ) /* wait for TI==1 */
306     {
307         WatchDog();
308         CpuIdle();
309     }
310     SBUF = Byte;
311     TI = 0;
312 }
313
314 /********************************************************************/
315 /* Function    : getchar()                                      SUB */
316 /*------------------------------------------------------------------*/
317 /* Description : everybody knows what this function is doing        */
318 /*------------------------------------------------------------------*/
319 /* Author      : Michael Schmitt                                    */
320 /*------------------------------------------------------------------*/
321 /* Input       : none                                               */
322 /*------------------------------------------------------------------*/
323 /* Returnvalue : char Byte                                          */
324 /*------------------------------------------------------------------*/
325 /* History     : 00/03    V1.0 Initial Version                      */
326 /*                                                                  */
327 /********************************************************************/
328 char getchar( void )
329 {
330     while( !RI ) /* wait for RI==1 */
331     {
332         WatchDog();
333         CpuIdle();
334     }
335     RI=0;
336     return (SBUF);
337 }
338
339 /********************************************************************/
340 /* Function    : keypressed()                                   SUB */
341 /*------------------------------------------------------------------*/
342 /* Description : is a char available ?                              */
343 /*------------------------------------------------------------------*/
344 /* Author      : Michael Schmitt                                    */
345 /*------------------------------------------------------------------*/
346 /* Input       : none                                               */
347 /*------------------------------------------------------------------*/
348 /* Returnvalue : TRUE yes, FALSE no                                 */
349 /*------------------------------------------------------------------*/
350 /* History     : 00/03    V1.0 Initial Version                      */
351 /*                                                                  */
352 /********************************************************************/
353 char keypressed( void )
354 {
355     unsigned char c;
356
357     if(RI)
358     {
359         c = TRUE;
360     }
361     else
362     {
363         c = FALSE;
364     }
365     return (c);
366 }
367
368 #endif
369
370 // ===========================================================================
371 // System Timer
372 #ifdef USE_SYSTEM_TIMER
373
374 volatile unsigned long SystemTicks1msec;
375
376 // Here are the definitions of the 1kHz Timer 0
377 // used for delay( xx_msec )
378 #ifndef CPUCLKHZ
379 #error "CPUCLKHZ is not defined !"
380 #endif
381
382 #define TIMER0INTSPERSECOND     1000
383 #define TIMER0MODE1RELOADVALUE  (-((CPUCLKHZ/TIMER0INTSPERSECOND)/12))
384
385 /********************************************************************/
386 /* Function    : delayMsec()                                    SUB */
387 /*------------------------------------------------------------------*/
388 /* Description : waste some CPU-Time, CPU will be set into IDLE Mode*/
389 /*               and is waked up every 1msec by TIMER0              */
390 /*------------------------------------------------------------------*/
391 /* Author      : Michael Schmitt                                    */
392 /*------------------------------------------------------------------*/
393 /* Input       : unsigned long delayTime                            */
394 /*------------------------------------------------------------------*/
395 /* Returnvalue : none                                               */
396 /*------------------------------------------------------------------*/
397 /* History     : 99/10    V1.0 Initial Version                      */
398 /*                                                                  */
399 /********************************************************************/
400 void DelayMsec( unsigned long delayTime )
401 {
402     delayTime += SystemTicks1msec;
403     WatchDog();
404     while( SystemTicks1msec < delayTime )
405     {
406         CpuIdle();
407         WatchDog();
408     }
409     WatchDog();
410 }
411
412 /********************************************************************/
413 /* Function    : timer0_isr                                     ISR */
414 /*------------------------------------------------------------------*/
415 /* Description : This ISR is called every 1msec and inc. a variable */
416 /*               that is used for delay()                           */
417 /*------------------------------------------------------------------*/
418 /* Author      : Michael Schmitt                                    */
419 /*------------------------------------------------------------------*/
420 /* Input       : none                                               */
421 /*------------------------------------------------------------------*/
422 /* Returnvalue : none                                               */
423 /*------------------------------------------------------------------*/
424 /* History     : 99/10    V1.0 Initial Version                      */
425 /*                                                                  */
426 /********************************************************************/
427 void timer0_isr (void) interrupt TF0_VECTOR
428 {
429     /* Interruptrate will be slightly slower than wanted */
430     /* because TL0 is not 0 here, not bug-fix yet */
431     TL0 = (TIMER0MODE1RELOADVALUE & 0x00FF);
432     TH0 = (TIMER0MODE1RELOADVALUE >> 8);
433     SystemTicks1msec++;
434 }
435 #endif // USE_SYSTEM_TIMER
436
437 // ===========================================================================
438 // Analog Stuff
439 #ifdef USE_ANALOGPORT
440
441 unsigned int ADCGetValue( char ADCPort )
442 {
443     // if a conversion is busy, wait
444     while( BSY )
445     {
446         //
447     }
448     WatchDog();
449
450     // set AD-Port
451     ADCON1 &= 0xF8;             // clear MX0 to MX2
452     ADCON1 |= (ADCPort & 0x07); // set Port
453
454     // start AD Conversion
455     ADDATL = 0x00;
456
457     while( BSY )
458     {
459         //
460     }
461     WatchDog();
462
463     // read AD Converter Register
464     return( (((unsigned int)ADDATH) << 2) + ((unsigned int)ADDATL >> 6) );
465 }
466 #endif
467
468 // ===========================================================================
469
470 // ===================================================================
471 // Global Hardware Init
472 /********************************************************************/
473 /* Function    : InitHardware()                                 SUB */
474 /*------------------------------------------------------------------*/
475 /* Description : Should be the first executed after reset to get a  */
476 /*               proper initalised CPU                              */
477 /*------------------------------------------------------------------*/
478 /* Author      : Michael Schmitt                                    */
479 /*------------------------------------------------------------------*/
480 /* Input       : none                                               */
481 /*------------------------------------------------------------------*/
482 /* Returnvalue : none                                               */
483 /*------------------------------------------------------------------*/
484 /* History     : 99/10    V1.0 Initial Version                      */
485 /*                                                                  */
486 /********************************************************************/
487 void InitHardware( void )
488 {
489 #ifdef USE_SYSTEM_TIMER
490     SystemTicks1msec = 0x0;
491 #endif // USE_SYSTEM_TIMER
492
493     EA = 0;         // Disable ALL Ints
494     ES = 0;         // Disable Serial Int
495     ET1 = 0;        // Disable Timer 1 Int
496     EX1 = 0;        // Disable External Interrupt 1
497     ET0 = 0;        // Disable Timer 0 Int
498     EX0 = 0;        // Disable External Interrupt 0
499     EADC = 0;       // Disable A/D Converter Interrupt
500
501     TR1 = 0;        // Stop Timer 1
502     TR0 = 0;        // Stop Timer 0
503
504     // The Siemens CPU C515A has 8 Analog inputs with 10Bit resolution
505     // Conversion Clock is generated from CPU-Clock but should be less
506     // than max 2MHZ.
507     if( CPUCLKHZ < 16000000 )
508     {
509         // CPU Speed < 16MHz Prescaler Ratio is divide by 4 (Reset default)
510         ADCON1 &= ~ADCON1_ADCL;
511         // the automatic A/D Converter Calibration needs
512         // Reset Calibration phase = 26624 / CPUCLKHZ
513         // @ 16MHz this is about 1,7msec
514         // or 2219 machine cycle
515     }
516     else
517     {
518         // CPU Speed > 16MHz Prescaler Ratio is divide by 4 (Reset default)
519         ADCON1 |= ADCON1_ADCL;
520         // the automatic A/D Converter Calibration needs
521         // Reset Calibration phase = 53248 / CPUCLKHZ
522         // @ 246MHz this is about 2,3msec
523         // or 4438 machine cycle
524     }
525
526
527     // AD-Conversion stars intern and not with P40 ADST#
528     ADCON0 &= ~ADCON0_ADM;
529
530 #ifdef USE_SYSTEM_TIMER
531     // Init Timer 0 as Software Interrupt for 1mSec Timer
532     TL0 = (TIMER0MODE1RELOADVALUE & 0x00FF);
533     TH0 = (TIMER0MODE1RELOADVALUE >> 8);
534     TMOD &= 0xf0;
535     TMOD |= 0x01;       // Setting Timer 0 als GATE=0 TIMER und MODE 1 16-bit Timer mode
536     TR0  = 1;           // Enabling Timer 0
537     TR0 = 1;            // Start Timer 0
538     ET0 = 1;            // Enable Timer 0 Interrupt
539 #endif
540
541 #ifdef SERIAL_VIA_INTERRUPT
542     // Ringbuffer for Serielle UART  init
543     SERIAL_VIA_INTERRUPT_RCNT = 0;
544     SERIAL_VIA_INTERRUPT_XCNT = 0;
545     SERIAL_VIA_INTERRUPT_RPOS = 0;
546     SERIAL_VIA_INTERRUPT_XPOS = 0;
547     SERIAL_VIA_INTERRUPT_BUSY = 0;
548 #endif
549
550 #ifdef SERIAL_IS_DEFINED
551 #ifdef BAUDRATEGENENATOR_USED
552
553     // We use the internal Bauratengenerator of the Siemens CPU
554     SRELL = (BAUDRATEGENRELOADVALUE & 0x00FF);
555     SRELH = (BAUDRATEGENRELOADVALUE >> 8);
556     ADCON0 |= 0x80; // set BD-Bit, we use internal Baudrate gen.
557     PCON |= 0x80;   // SMOD-Bit forr double Baudrate
558
559 #else
560
561     // use TIMER1 im Mode 2
562     PCON |= 0x80;   // set SMOD-Bit for double Baudrate
563     TH1 = TIMER1MODE2RELOADVALUE;
564     TL1 = TIMER1MODE2RELOADVALUE;
565     TMOD &= 0x0f;
566     TMOD |= 0x20;   // Timer 1 als GATE=0 TIMER und MODE 2 8-bit auto reload
567     TR1  = 1;       // Enabling Timer 1
568
569 #endif
570
571     SCON  = 0x40;       // Init Serial Port as 8-Bit UART
572     SCON |= 0x10;       // Enabling Seriel receive REN-Bit
573     SCON |= 0x02;       // Setting TI-Bit
574
575 #ifdef SERIAL_VIA_INTERRUPT
576         ES = 1;         // Enable Serial Interrupt
577 #endif
578
579 #endif
580
581 #ifdef USE_CPU_Internal_XRAM
582     // CPU Internal SRAM einable
583     SYSCON = ((SYSCON) & ((UBYTE)~(XMAP0_BIT | XMAP1_BIT)));
584 #endif
585
586     EA = 1;             // Enable all Enabled Interrupts
587 }
588
589 #endif