Imported Upstream version 2.9.0
[debian/cc1111] / device / examples / mcs51 / simple / hi.c
1 /*------------------------------------------------------------------------
2  hi.c - This is a simple program designed to operate on basic MCS51
3    hardware at 11.0592Mhz.  It sets up the baudrate to 9600 and sends
4    a "Hi\n" "There\n" message every few seconds.  The timer interrupt
5    is used.
6
7    Its intended to be a simple example for SDCC, a good first
8    program to compile and play with.
9
10    The simulator can be used to run this program:
11    s51 -Sout=serial.txt hi.ihx (run, stop, quit)
12
13    Notice that unless we use the --stack-after-data option,
14    the SSEG listed in the map is not accurate, look at the
15    .asm file and search for "sp," to see where it is really
16    initialized to.
17
18  6-28-01  Written by Karl Bongers(karl@turbobit.com)
19 |------------------------------------------------------------------------*/
20 #include <8052.h>
21
22 typedef unsigned char byte;
23 typedef unsigned int word;
24 typedef unsigned long l_word;
25
26 //---- most of the following declares are simply to demostrate some
27 // of SDCC's variable storage declaration syntax
28
29 // volatile keyword is needed for variables shared by interrupt routine
30 // and normal application thread, otherwise things get optimized out.
31 volatile data byte timer;
32 volatile data byte hi_flag;
33
34 data byte a_data_byte;    // normal < 128 bytes of 8031 internal memory.
35 idata byte a_idata_byte;  // in +128 byte internal memory of 8032
36 xdata byte a_xdata_byte;  // in external memory.
37 xdata at 0x8000 byte mem_mapped_hardware; // example at usage
38
39 bit my_bit;  // mcs51 bit variable, stored in single bit of register space
40
41 sfr at 0xd8 WDCON;  // special function register declaration
42 sbit LED_SYS = 0xb5;  // P3.5 is led, example use of sbit keyword
43
44 code char my_message[] = {"GNU rocks\n"};  // placed in code space
45
46 void timer0_irq_proc(void) interrupt 1 using 2;
47
48 /*------------------------------------------------------------------------
49   timer0_int - Timer0 interrupt.  Notice we are using register bank 2
50     for this interrupt.
51 |------------------------------------------------------------------------*/
52 void timer0_irq_proc(void) interrupt 1 using 2
53 {
54   if (timer != 0)
55   {
56     --timer;
57   }
58   else
59   {
60     hi_flag = 1;
61     timer = 250;
62   }
63
64   TR0 = 0; /* Stop Timer 0 counting */
65   TH0 = (~(5000)) >> 8;
66   TL0 = (~(5000)) & 0xff;
67   TR0 = 1; /* Start counting again */
68 }
69
70 #if 0
71 /*------------------------------------------------------------------------
72   uart0_int - Interrupt 4 is for the UART, notice we use register bank 1
73     for the interrupt routine.
74 |------------------------------------------------------------------------*/
75 void uart0_int(void) interrupt 4 using 1
76 {
77   if (RI)
78   {
79     c = SBUF;
80     RI = 0;
81   }
82 }
83 #endif
84
85 /*------------------------------------------------------------------------
86   tx_char - transmit(tx) a char out the serial uart.
87 |------------------------------------------------------------------------*/
88 void tx_char(char c)
89 {
90   SBUF = c;
91   while (!TI)
92     ;
93   TI = 0;
94 }
95
96 /*------------------------------------------------------------------------
97   tx_str - transmit(tx) a string out the serial uart.
98 |------------------------------------------------------------------------*/
99 void tx_str(char *str)
100 {
101   
102   while (*str)
103     tx_char(*str++);
104 }
105
106 /*------------------------------------------------------------------------
107   stop - a break point in Daniel D's s51 can be set at 65535 memory
108     location to stop the simulation.  This routine also shows how to
109     embed assembly.
110 |------------------------------------------------------------------------*/
111 void stop(void)
112 {
113  _asm;
114   mov dptr, #65535;
115   movx a, @dptr;
116   nop;
117  _endasm;
118 }
119
120 /*------------------------------------------------------------------------
121   main - Simple test program to send out something to the serial port.
122 |------------------------------------------------------------------------*/
123 void main(void)
124 {
125   PCON = 0x80;  /* power control byte, set SMOD bit for serial port */
126   SCON = 0x50;  /* serial control byte, mode 1, RI active */
127   TMOD = 0x21;  /* timer control mode, byte operation */
128   TCON = 0;     /* timer control register, byte operation */
129
130   TH1 = 0xFA;   /* serial reload value, 9,600 baud at 11.0952Mhz */
131   TR1 = 1;      /* start serial timer */
132
133   TR0 = 1;      /* start timer0 */
134   ET0 = 1;      /* Enable Timer 0 overflow interrupt IE.1 */
135   EA = 1;       /* Enable Interrupts */
136
137   TI = 0;       /* clear this out */
138   SBUF = '.';   /* send an initial '.' out serial port */
139   hi_flag = 1;
140   //ES = 1;                           /* Enable serial interrupts IE.4 */
141
142   tx_str(my_message);
143
144   for (;;)
145   {
146     if (hi_flag)
147     {
148       tx_str("Hi There\n");
149       hi_flag = 0;
150     }
151
152 stop();
153
154 #ifdef TEST_IDLE_MODE
155     // this was a simple test of the low power sleep mode of a
156     // dallas DS5000 cmos part, to see how much power requirements
157     // dropped in sleep mode.
158     
159     // into idle mode until next interrupt.  Draws only 3ma.
160     PCON = 0x81;
161 #endif
162   }
163
164 }
165