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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [example/] [demo_xip/] [main.c] - Blame information for rev 70

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 70 zero_gravi
// #################################################################################################
2
// # << NEORV32 - Demo for the Execute In Place (XIP) Module >>                                    #
3
// # ********************************************************************************************* #
4
// # BSD 3-Clause License                                                                          #
5
// #                                                                                               #
6
// # Copyright (c) 2022, Stephan Nolting. All rights reserved.                                     #
7
// #                                                                                               #
8
// # Redistribution and use in source and binary forms, with or without modification, are          #
9
// # permitted provided that the following conditions are met:                                     #
10
// #                                                                                               #
11
// # 1. Redistributions of source code must retain the above copyright notice, this list of        #
12
// #    conditions and the following disclaimer.                                                   #
13
// #                                                                                               #
14
// # 2. Redistributions in binary form must reproduce the above copyright notice, this list of     #
15
// #    conditions and the following disclaimer in the documentation and/or other materials        #
16
// #    provided with the distribution.                                                            #
17
// #                                                                                               #
18
// # 3. Neither the name of the copyright holder nor the names of its contributors may be used to  #
19
// #    endorse or promote products derived from this software without specific prior written      #
20
// #    permission.                                                                                #
21
// #                                                                                               #
22
// # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS   #
23
// # OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF               #
24
// # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE    #
25
// # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,     #
26
// # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE #
27
// # GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED    #
28
// # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING     #
29
// # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED  #
30
// # OF THE POSSIBILITY OF SUCH DAMAGE.                                                            #
31
// # ********************************************************************************************* #
32
// # The NEORV32 Processor - https://github.com/stnolting/neorv32              (c) Stephan Nolting #
33
// #################################################################################################
34
 
35
 
36
/**********************************************************************//**
37
 * @file demo_xip/main.c
38
 * @author Stephan Nolting
39
 * @brief Demo for the the execute in place (XIP) module.
40
 **************************************************************************/
41
 
42
#include <neorv32.h>
43
 
44
 
45
/**********************************************************************//**
46
 * @name User configuration
47
 **************************************************************************/
48
/**@{*/
49
/** UART BAUD rate */
50
#define BAUD_RATE 19200
51
/**@}*/
52
 
53
 
54
/**********************************************************************//**
55
 * @name Prototypes
56
 **************************************************************************/
57
int program_xip_flash(void);
58
 
59
 
60
/**********************************************************************//**
61
 * @name Simple program to be stored to the XIP flash.
62
 * This is the "blink_led_asm" from the rv32i-version "blink_led" demo program.
63
 **************************************************************************/
64
const uint32_t xip_program[] = {
65
  0xfc800513,
66
  0x00052023,
67
  0x00000313,
68
  0x0ff37313,
69
  0x00652023,
70
  0x00130313,
71
  0x008000ef,
72
  0xff1ff06f,
73
  0x001003b7,
74
  0xfff38393,
75
  0x00038a63,
76
  0xfff38393,
77
  0x00000013,
78
  0x00000013,
79
  0xff1ff06f,
80
  0x00008067
81
};
82
 
83
 
84
/**********************************************************************//**
85
 * Main function: configure the XIP module, program a small program to the attached flash
86
 * and run that program **from there**. The program shows an incrementing counter at the lowest
87
 * 8-bits of the GPIO output port. This demo is meant for a SPI flash/EEPROM with 16-bit addresses.
88
 *
89
 * @note This program requires the XIP module, UART0 and the GPIO module.
90
 *
91
 * @return 0 if execution was successful
92
 **************************************************************************/
93
int main() {
94
 
95
  // init UART at default baud rate, no parity bits, no HW flow control
96
  neorv32_uart0_setup(BAUD_RATE, PARITY_NONE, FLOW_CONTROL_NONE);
97
 
98
  // capture all exceptions and give debug info via UART
99
  // this is not required, but keeps us safe
100
  neorv32_rte_setup();
101
 
102
  // check if XIP module is implemented at all
103
  if (neorv32_xip_available() == 0) {
104
    neorv32_uart0_printf("Error! XIP module not synthesized!\n");
105
    return 1;
106
  }
107
 
108
 
109
  // intro
110
  neorv32_uart0_printf("<< XIP Demo Program >>\n\n");
111
 
112
 
113
  // warning if i-cache is not implemented
114
  if ((NEORV32_SYSINFO.SOC & (1 << SYSINFO_SOC_ICACHE)) == 0) {
115
    neorv32_uart0_printf("WARNING! No instruction cache implemented. The XIP program will run awfully slow...\n");
116
  }
117
 
118
 
119
  // reset XIP module and configure basic SPI properties
120
  // * 1/64 clock divider
121
  // * clock mode 0 (cpol = 0, cpha = 0)
122
  // * flash read command = 0x03
123
  // -> this function will also send 64 dummy clock cycles via the XIP's SPI port (with CS disabled)
124
  if (neorv32_xip_init(CLK_PRSC_64, 0, 0, 0x03)) {
125
    neorv32_uart0_printf("Error! XIP module setup error!\n");
126
    return 1;
127
  }
128
 
129
  // use a helper function to store a small example program to the XIP flash
130
  // NOTE: this (direct SPI access via the XIP module) has to be done before the actual XIP mode is enabled!
131
  neorv32_uart0_printf("Programming XIP flash...\n");
132
  if (program_xip_flash()) {
133
    neorv32_uart0_printf("Error! XIP flash programming error!\n");
134
    return 1;
135
  }
136
 
137
  // configure and enable the actual XIP mode
138
  // * configure 2 address bytes send to the SPI flash for addressing
139
  // * map the XIP flash to the address space starting at 0x20000000
140
  if (neorv32_xip_start(2, 0x20000000)) {
141
    neorv32_uart0_printf("Error! XIP mode configuration error!\n");
142
    return 1;
143
  }
144
 
145
  // finally, jump to the XIP flash's base address we have configured to start execution **from there**
146
  neorv32_uart0_printf("Starting Execute-In-Place program...\n");
147
  asm volatile ("call %[dest]" : : [dest] "i" (0x20000000));
148
 
149
  return 0;
150
}
151
 
152
 
153
/**********************************************************************//**
154
 * Helper function to program the XIP flash via the direct SPI feature of the XIP module.
155
 *
156
 * @warning This function can only be used BEFORE the XIP-mode is activated!
157
 * @note This function is blocking.
158
 *
159
 * @return Returns 0 if write was successful.
160
 **************************************************************************/
161
int program_xip_flash(void) {
162
 
163
  int error = 0;
164
  uint32_t data_byte = 0;
165
  uint32_t cnt = 0;
166
  uint32_t flash_addr = 0;
167
  uint32_t tmp = 0;
168
 
169
  union {
170
    uint64_t uint64;
171
    uint32_t uint32[sizeof(uint64_t)/2];
172
  } data;
173
 
174
  while (1) {
175
 
176
    // get data byte
177
    data_byte = xip_program[cnt/4];
178
    data_byte >>= (3-(cnt & 3)) * 8;
179
    data_byte &= 0x000000FF;
180
 
181
//DEBUGGING
182
//neorv32_uart0_printf("Data byte %u: 0x%x\n", cnt, data_byte);
183
 
184
    // set write-enable latch
185
    // 1 byte command
186
    data.uint32[0] = 0; // irrelevant, TX packet is MSB-aligned
187
    data.uint32[1] = 0x06 << 24; // command: set write-enable latch
188
    error += neorv32_xip_spi_trans(1, &data.uint64);
189
 
190
    // write word
191
    // 1 byte command, 2 bytes address, 1 byte data
192
    tmp = 0x02 << 24; // command: byte write
193
    tmp |= (flash_addr & 0x0000FFFF) << 8; // address
194
    tmp |= data_byte << 0; // data byte
195
    data.uint32[0] = 0; // irrelevant, TX packet is MSB-aligned
196
    data.uint32[1] = tmp;
197
    error += neorv32_xip_spi_trans(4, &data.uint64);
198
    flash_addr++;
199
 
200
    // check status register: WIP bit has to clear
201
    while(1) {
202
      tmp = 0x05 << 24; // read status register command
203
      data.uint32[0] = 0; // irrelevant, TX packet is MSB-aligned
204
      data.uint32[1] = tmp;
205
      error += neorv32_xip_spi_trans(2, &data.uint64);
206
      if ((data.uint32[0] & 0x01) == 0) { // WIP bit cleared?
207
        break;
208
      }
209
    }
210
 
211
    // done?
212
    cnt++;
213
    if ((cnt == ((uint32_t)sizeof(xip_program))) || (error != 0)) {
214
      break;
215
    }
216
  }
217
 
218
  return error;
219
}

powered by: WebSVN 2.1.0

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