1 /*
2 * FreeRTOS V202212.00
3 * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
6 * this software and associated documentation files (the "Software"), to deal in
7 * the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 * the Software, and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * https://www.FreeRTOS.org
23 * https://github.com/FreeRTOS
24 *
25 */
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 #include <sys/types.h>
31
32 void uart_init( void );
33 #ifndef __PICOLIBC__
34 __attribute__( ( used ) ) int _fstat( int file );
35 int _read( int file,
36 char * buf,
37 int len );
38 int _write( int file,
39 char * buf,
40 int len );
41
42 void * _sbrk( int incr );
43 #endif
44
45 typedef struct UART_t
46 {
47 volatile uint32_t DATA;
48 volatile uint32_t STATE;
49 volatile uint32_t CTRL;
50 volatile uint32_t INTSTATUS;
51 volatile uint32_t BAUDDIV;
52 } UART_t;
53
54 #define UART0_ADDR ( ( UART_t * ) ( 0x40004000 ) )
55 #define UART_DR( baseaddr ) ( *( unsigned int * ) ( baseaddr ) )
56
57 #define UART_CTRL_TX_EN ( 1 << 0 )
58
59
60 #ifndef __PICOLIBC__
61 extern unsigned long _heap_bottom;
62 extern unsigned long _heap_top;
63
64 static char * heap_end = ( char * ) &_heap_bottom;
65 #endif
66
67 /**
68 * @brief initializes the UART emulated hardware
69 */
uart_init(void)70 void uart_init( void )
71 {
72 UART0_ADDR->BAUDDIV = 16;
73 UART0_ADDR->CTRL = UART_CTRL_TX_EN;
74 }
75
76 #ifdef __PICOLIBC__
77
78 #include <stdio.h>
79
80 int
_uart_putc(char c,FILE * file)81 _uart_putc(char c, FILE *file)
82 {
83 ( void ) file;
84
85 UART_DR( UART0_ADDR ) = c;
86 return (unsigned char) c;
87 }
88
89 static FILE __stdio = FDEV_SETUP_STREAM(_uart_putc, NULL, NULL, _FDEV_SETUP_WRITE);
90 __attribute__( ( used ) ) FILE *const stdout = &__stdio;
91
92 #else
93
94 /**
95 * @brief not used anywhere in the code
96 * @todo implement if necessary
97 *
98 */
_fstat(int file)99 int _fstat( int file )
100 {
101 ( void ) file;
102 return 0;
103 }
104
105 /**
106 * @brief not used anywhere in the code
107 * @todo implement if necessary
108 *
109 */
_read(int file,char * buf,int len)110 int _read( int file,
111 char * buf,
112 int len )
113 {
114 ( void ) file;
115 ( void ) buf;
116 ( void ) len;
117 return -1;
118 }
119
120 /**
121 * @brief Write bytes to the UART channel to be displayed on the command line
122 * with qemu
123 * @param [in] file ignored
124 * @param [in] buf buffer to send
125 * @param [in] len length of the buffer
126 * @returns the number of bytes written
127 */
_write(int file,char * buf,int len)128 int _write( int file,
129 char * buf,
130 int len )
131 {
132 int todo;
133
134 ( void ) file;
135
136 for( todo = 0; todo < len; todo++ )
137 {
138 UART_DR( UART0_ADDR ) = *buf++;
139 }
140
141 return len;
142 }
143
144 /**
145 * @brief function called by malloc and friends to reserve memory on the heap
146 * @param [in] incr the amount of bytes to increase or decrease
147 * @returns the previous top of the heap
148 * @note uses a global variable <b>heap_end</b> to keep track of the previous top
149 */
_sbrk(int incr)150 void * _sbrk( int incr )
151 {
152 void * prev_heap_end = heap_end;
153
154 if( ( heap_end + incr ) > ( char * ) &_heap_top )
155 {
156 return ( void * ) -1;
157 }
158
159 heap_end += incr;
160
161 return prev_heap_end;
162 }
163 #endif
164
165 #ifdef __cplusplus
166 }
167 #endif
168