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