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 /*------------------------------------------------------------------*/
10 /*------------------------------------------------------------------*/
11 /* Returnvalue : none */
12 /*------------------------------------------------------------------*/
13 /* History : 00/03 V1.0 Initial Version */
15 /********************************************************************/
16 #ifndef __FILE_CPU_C515A
17 #define __FILE_CPU_C515A
19 // All that has to be included and / or defined is done here
21 #include "../inc/hardware_describtion.h"
23 // END INCLUDES & DEFINES ===========================================
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 /*------------------------------------------------------------------*/
33 /*------------------------------------------------------------------*/
34 /* Returnvalue : none */
35 /*------------------------------------------------------------------*/
36 /* History : 00/03 V1.0 Initial Version */
38 /********************************************************************/
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
45 // wait until AD-Conversion is finished
53 #ifdef USE_SYSTEM_TIMER
54 PCON |= 0x01; // IDL-Bit in register PCON starts IDLE Mode
57 // If there is no regular INT source, we better do not use
64 /********************************************************************/
65 /* Function : WatchDog() SUB */
66 /*------------------------------------------------------------------*/
67 /* Description : Internal (and external) Watchdogs trigger */
68 /*------------------------------------------------------------------*/
69 /* Author : Michael Schmitt */
70 /*------------------------------------------------------------------*/
72 /*------------------------------------------------------------------*/
73 /* Returnvalue : none */
74 /*------------------------------------------------------------------*/
75 /* History : 00/03 V1.0 Initial Version */
77 /********************************************************************/
82 // retrigger Externer Watchdog
83 // Interner Watchdog not yet implemented
87 // ===========================================================================
88 // Serial IO with the internal UART in Interrupt Mode
89 #ifdef SERIAL_VIA_INTERRUPT
91 #define SERIAL_IS_DEFINED
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
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
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;
114 #endif // SERIAL_VIA_INTERRUPT
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
122 #ifdef SERIAL_IS_DEFINED
123 // calculate the reloadvalues acc. to the definitions
125 #error "CPUCLKHZ not defined !"
128 #error "BAUDRATE not defined !"
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 #define BAUDRATEGENENATOR_USED
133 #define BAUDRATEGENRELOADVALUE (1024-(2*CPUCLKHZ/64/BAUDRATE))
134 #define TIMER1MODE2RELOADVALUE (256-(2*CPUCLKHZ/32/12/BAUDRATE))
136 #endif // SERIAL_IS_DEFINED
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 /*------------------------------------------------------------------*/
152 /*------------------------------------------------------------------*/
153 /* Returnvalue : none */
154 /*------------------------------------------------------------------*/
155 /* History : 00/03 V1.0 Initial Version */
157 /********************************************************************/
158 void SERIALVIAINTERRUPT (void) interrupt SI0_VECTOR
163 // char that are already inside the buffer should not be overwritten
164 if (SERIAL_VIA_INTERRUPT_RCNT < SERIAL_VIA_INTERRUPT_RBUFLEN)
166 SERIAL_VIA_INTERRUPT_RBUF [(SERIAL_VIA_INTERRUPT_RPOS+SERIAL_VIA_INTERRUPT_RCNT++) % SERIAL_VIA_INTERRUPT_RBUFLEN] = SBUF;
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)
178 SERIAL_VIA_INTERRUPT_XPOS = 0;
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 */
197 /********************************************************************/
198 void putchar( char Byte )
200 while (SERIAL_VIA_INTERRUPT_XCNT >= SERIAL_VIA_INTERRUPT_XBUFLEN)
202 // buffer is full, wait until room
208 if (SERIAL_VIA_INTERRUPT_BUSY)
210 SERIAL_VIA_INTERRUPT_XBUF[(SERIAL_VIA_INTERRUPT_XPOS+SERIAL_VIA_INTERRUPT_XCNT++) % SERIAL_VIA_INTERRUPT_XBUFLEN] = Byte;
215 SERIAL_VIA_INTERRUPT_BUSY = 1;
220 /********************************************************************/
221 /* Function : getchar() SUB */
222 /*------------------------------------------------------------------*/
223 /* Description : everybody knows what this function is doing */
224 /*------------------------------------------------------------------*/
225 /* Author : Michael Schmitt */
226 /*------------------------------------------------------------------*/
228 /*------------------------------------------------------------------*/
229 /* Returnvalue : char Byte */
230 /*------------------------------------------------------------------*/
231 /* History : 00/03 V1.0 Initial Version */
233 /********************************************************************/
234 unsigned char getchar( void )
237 while (!SERIAL_VIA_INTERRUPT_RCNT)
239 // no char avail, so wait
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)
248 SERIAL_VIA_INTERRUPT_RPOS = 0;
255 /********************************************************************/
256 /* Function : keypressed() SUB */
257 /*------------------------------------------------------------------*/
258 /* Description : checks, if a char is available */
259 /*------------------------------------------------------------------*/
260 /* Author : Michael Schmitt */
261 /*------------------------------------------------------------------*/
263 /*------------------------------------------------------------------*/
264 /* Returnvalue : TRUE yes, FALSE no */
265 /*------------------------------------------------------------------*/
266 /* History : 00/03 V1.0 Initial Version */
268 /********************************************************************/
269 unsigned char keypressed( void )
273 if(SERIAL_VIA_INTERRUPT_RCNT)
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 */
302 /********************************************************************/
303 void putchar( char Byte )
305 while( !TI ) /* wait for TI==1 */
314 /********************************************************************/
315 /* Function : getchar() SUB */
316 /*------------------------------------------------------------------*/
317 /* Description : everybody knows what this function is doing */
318 /*------------------------------------------------------------------*/
319 /* Author : Michael Schmitt */
320 /*------------------------------------------------------------------*/
322 /*------------------------------------------------------------------*/
323 /* Returnvalue : char Byte */
324 /*------------------------------------------------------------------*/
325 /* History : 00/03 V1.0 Initial Version */
327 /********************************************************************/
328 unsigned char getchar( void )
330 while( !RI ) /* wait for RI==1 */
339 /********************************************************************/
340 /* Function : keypressed() SUB */
341 /*------------------------------------------------------------------*/
342 /* Description : is a char available ? */
343 /*------------------------------------------------------------------*/
344 /* Author : Michael Schmitt */
345 /*------------------------------------------------------------------*/
347 /*------------------------------------------------------------------*/
348 /* Returnvalue : TRUE yes, FALSE no */
349 /*------------------------------------------------------------------*/
350 /* History : 00/03 V1.0 Initial Version */
352 /********************************************************************/
353 unsigned char keypressed( void )
370 // ===========================================================================
372 #ifdef USE_SYSTEM_TIMER
374 volatile unsigned long SystemTicks1msec;
376 // Here are the definitions of the 1kHz Timer 0
377 // used for delay( xx_msec )
379 #error "CPUCLKHZ is not defined !"
382 #define TIMER0INTSPERSECOND 1000
383 #define TIMER0MODE1RELOADVALUE (-((CPUCLKHZ/TIMER0INTSPERSECOND)/12))
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 */
399 /********************************************************************/
400 void DelayMsec( unsigned long delayTime )
402 delayTime += SystemTicks1msec;
404 while( SystemTicks1msec < delayTime )
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 /*------------------------------------------------------------------*/
421 /*------------------------------------------------------------------*/
422 /* Returnvalue : none */
423 /*------------------------------------------------------------------*/
424 /* History : 99/10 V1.0 Initial Version */
426 /********************************************************************/
427 void timer0_isr (void) interrupt TF0_VECTOR
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);
435 #endif // USE_SYSTEM_TIMER
437 // ===========================================================================
439 #ifdef USE_ANALOGPORT
441 unsigned int ADCGetValue( char ADCPort )
443 // if a conversion is busy, wait
451 ADCON1 &= 0xF8; // clear MX0 to MX2
452 ADCON1 |= (ADCPort & 0x07); // set Port
454 // start AD Conversion
463 // read AD Converter Register
464 return( (((unsigned int)ADDATH) << 2) + ((unsigned int)ADDATL >> 6) );
468 // ===========================================================================
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 /*------------------------------------------------------------------*/
481 /*------------------------------------------------------------------*/
482 /* Returnvalue : none */
483 /*------------------------------------------------------------------*/
484 /* History : 99/10 V1.0 Initial Version */
486 /********************************************************************/
487 void InitHardware( void )
489 #ifdef USE_SYSTEM_TIMER
490 SystemTicks1msec = 0x0;
491 #endif // USE_SYSTEM_TIMER
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
501 TR1 = 0; // Stop Timer 1
502 TR0 = 0; // Stop Timer 0
504 // The Siemens CPU C515A has 8 Analog inputs with 10Bit resolution
505 // Conversion Clock is generated from CPU-Clock but should be less
507 if( CPUCLKHZ < 16000000 )
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
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
527 // AD-Conversion stars intern and not with P40 ADST#
528 ADCON0 &= ~ADCON0_ADM;
530 #ifdef USE_SYSTEM_TIMER
531 // Init Timer 0 as Software Interrupt for 1mSec Timer
532 TL0 = (TIMER0MODE1RELOADVALUE & 0x00FF);
533 TH0 = (TIMER0MODE1RELOADVALUE >> 8);
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
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;
550 #ifdef SERIAL_IS_DEFINED
551 #ifdef BAUDRATEGENENATOR_USED
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
561 // use TIMER1 im Mode 2
562 PCON |= 0x80; // set SMOD-Bit for double Baudrate
563 TH1 = TIMER1MODE2RELOADVALUE;
564 TL1 = TIMER1MODE2RELOADVALUE;
566 TMOD |= 0x20; // Timer 1 als GATE=0 TIMER und MODE 2 8-bit auto reload
567 TR1 = 1; // Enabling Timer 1
571 SCON = 0x40; // Init Serial Port as 8-Bit UART
572 SCON |= 0x10; // Enabling Seriel receive REN-Bit
573 SCON |= 0x02; // Setting TI-Bit
575 #ifdef SERIAL_VIA_INTERRUPT
576 ES = 1; // Enable Serial Interrupt
581 #ifdef USE_CPU_Internal_XRAM
582 // CPU Internal SRAM einable
583 SYSCON = ((SYSCON) & ((UBYTE)~(XMAP0_BIT | XMAP1_BIT)));
586 EA = 1; // Enable all Enabled Interrupts