OpenCores
URL https://opencores.org/ocsvn/neo430/neo430/trunk

Subversion Repositories neo430

[/] [neo430/] [trunk/] [neo430/] [sw/] [example/] [uart_irq/] [main.c] - Blame information for rev 198

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 198 zero_gravi
// #################################################################################################
2
// #  < UART interrupt example >                                                                   #
3
// # ********************************************************************************************* #
4
// # UART RECEIVE is conducted using the UART RX interrupt                                         #
5
// # UART TRANSMIT is conducted by using the timer interrupt                                       #
6
// # ********************************************************************************************* #
7
// # BSD 3-Clause License                                                                          #
8
// #                                                                                               #
9
// # Copyright (c) 2020, Stephan Nolting. All rights reserved.                                     #
10
// #                                                                                               #
11
// # Redistribution and use in source and binary forms, with or without modification, are          #
12
// # permitted provided that the following conditions are met:                                     #
13
// #                                                                                               #
14
// # 1. Redistributions of source code must retain the above copyright notice, this list of        #
15
// #    conditions and the following disclaimer.                                                   #
16
// #                                                                                               #
17
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
18
// #    conditions and the following disclaimer in the documentation and/or other materials        #
19
// #    provided with the distribution.                                                            #
20
// #                                                                                               #
21
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
22
// #    endorse or promote products derived from this software without specific prior written      #
23
// #    permission.                                                                                #
24
// #                                                                                               #
25
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
26
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
27
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
28
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
29
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
30
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
31
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
32
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
33
// # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
34
// # ********************************************************************************************* #
35
// # The NEO430 Processor - https://github.com/stnolting/neo430                                    #
36
// #################################################################################################
37
 
38
 
39
// Libraries
40
#include <stdint.h>
41
#include <neo430.h>
42
 
43
// Configuration
44
#define BAUD_RATE 19200
45
#define UART_FIFO_SIZE 512 // must be a power of two!
46
#define UART_FIFO_MASK (UART_FIFO_SIZE-1)
47
 
48
// Types
49
struct uart_fifo {
50
  uint8_t data[UART_FIFO_SIZE];
51
  uint16_t get_pnt;
52
  uint16_t put_pnt;
53
};
54
 
55
// Global vars
56
volatile struct uart_fifo uart_rtx_fifo;
57
 
58
// Function prototypes
59
void __attribute__((__interrupt__)) uart_irq_handler(void);
60
void __attribute__((__interrupt__)) timer_irq_handler(void);
61
void __attribute__((__interrupt__)) gpio_irq_handler(void);
62
 
63
void fifo_put_string(volatile struct uart_fifo *fifo, char *s);
64
uint8_t fifo_put(volatile struct uart_fifo *fifo, uint8_t c);
65
uint8_t fifo_get(volatile struct uart_fifo *fifo, uint8_t *c);
66
 
67
/* ------------------------------------------------------------
68
 * INFO Main function
69
 * ------------------------------------------------------------ */
70
int main(void) {
71
 
72
  // setup UART
73
  neo430_uart_setup(BAUD_RATE);
74
 
75
 
76
  // init fifo
77
  uart_rtx_fifo.get_pnt = 0;
78
  uart_rtx_fifo.put_pnt = 0;
79
 
80
  // deactivate all LEDs
81
  GPIO_OUTPUT = 0;
82
 
83
  // set address of UART, TIMER and GPIO IRQ handlers
84
  IRQVEC_SERIAL = (uint16_t)(&uart_irq_handler);
85
  IRQVEC_TIMER  = (uint16_t)(&timer_irq_handler);
86
  IRQVEC_GPIO   = (uint16_t)(&gpio_irq_handler);
87
 
88
  // configure GPIO pin-change interrupt
89
  GPIO_IRQMASK = 0xFFFF; // use all input pins as trigger
90
 
91
  // configure UART RX interrupt
92
  UART_CT |= (1<<UART_CT_RX_IRQ);
93
 
94
  // configure TIMER period
95
  neo430_timer_disable();
96
  TMR_THRES = 1;
97
 
98
  // configure timer operation
99
  TMR_CT = (1<<TMR_CT_EN)   | // enable timer
100
           (1<<TMR_CT_ARST) | // auto reset on threshold match
101
           (1<<TMR_CT_IRQ)  | // enable IRQ
102
           (1<<TMR_CT_RUN)  | // make timer run
103
           (TMR_PRSC_4096<<TMR_CT_PRSC0);
104
 
105
 
106
  // write string to buffer
107
  fifo_put_string(&uart_rtx_fifo, "\r\nUART IRQ FIFO Echo Test\r\n");
108
 
109
  // enable global IRQs
110
  neo430_eint();
111
 
112
  while(1) {
113
    neo430_sleep();
114
  }
115
 
116
  return 0;
117
}
118
 
119
 
120
 
121
/* ------------------------------------------------------------
122
 * INFO UART interrupt handler
123
 * INFO Put received char into buffer
124
 * ------------------------------------------------------------ */
125
void __attribute__((__interrupt__)) uart_irq_handler(void) {
126
 
127
  fifo_put(&uart_rtx_fifo, (uint8_t)neo430_uart_char_read());
128
}
129
 
130
 
131
 
132
/* ------------------------------------------------------------
133
 * INFO Timer interrupt handler
134
 * INFO Send char from buffer if available
135
 * ------------------------------------------------------------ */
136
void __attribute__((__interrupt__)) timer_irq_handler(void) {
137
 
138
  uint8_t c;
139
 
140
  // UART transceiver idle?
141
  if ((UART_CT & (1<<UART_CT_TX_BUSY)) == 0) {
142
    // char in buffer available?
143
    if (fifo_get(&uart_rtx_fifo, &c) == 0) {
144
      UART_RTX = (uint16_t)c;
145
    }
146
  }
147
}
148
 
149
/* ------------------------------------------------------------
150
 * INFO Write string to buffer, blocking!
151
 * ------------------------------------------------------------ */
152
void fifo_put_string(volatile struct uart_fifo *fifo, char *s) {
153
 
154
  uint8_t c = 0;
155
  while ((c = (uint8_t)*s++))
156
    fifo_put(fifo, c);
157
}
158
 
159
 
160
/* ------------------------------------------------------------
161
 * INFO Write to buffer, return 0 if success
162
 * ------------------------------------------------------------ */
163
uint8_t fifo_put(volatile struct uart_fifo *fifo, uint8_t c) {
164
 
165
  uint16_t next = ((fifo->put_pnt + 1) & UART_FIFO_MASK);
166
 
167
  if (fifo->get_pnt == next)
168
    return 1; // fifo full
169
 
170
  fifo->data[fifo->put_pnt & UART_FIFO_MASK] = c;
171
  fifo->put_pnt = next;
172
 
173
  return 0;
174
}
175
 
176
 
177
/* ------------------------------------------------------------
178
 * INFO Read from buffer, returns 0 if success
179
 * ------------------------------------------------------------ */
180
uint8_t fifo_get(volatile struct uart_fifo *fifo, uint8_t *c) {
181
 
182
  if (fifo->get_pnt == fifo->put_pnt)
183
    return 1; // fifo empty
184
 
185
  *c = fifo->data[fifo->get_pnt];
186
 
187
  fifo->get_pnt = (fifo->get_pnt+1) & UART_FIFO_MASK;
188
 
189
  return 0;
190
}
191
 
192
 
193
 
194
/* ------------------------------------------------------------
195
 * INFO GPIO pin-change interrupt handler
196
 * ------------------------------------------------------------ */
197
void __attribute__((__interrupt__)) gpio_irq_handler(void) {
198
 
199
  GPIO_OUTPUT = (GPIO_OUTPUT + 1) & 0x00FF; // increment LED counter
200
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.