summaryrefslogtreecommitdiff
path: root/ecos/packages/hal/cortexm/stm32/stm32x0g_eval/current/src/stm32x0g_eval_misc.c
blob: 84a5a0a2fc7835d9a00e7cad369d824ac7e0ddee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
/*==========================================================================
//
//      stm32x0g_eval_misc.c
//
//      Cortex-M3/-M4 STM32X0G EVAL HAL functions
//
//==========================================================================
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
// -------------------------------------------                              
// This file is part of eCos, the Embedded Configurable Operating System.   
// Copyright (C) 2008, 2011, 2012 Free Software Foundation, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under    
// the terms of the GNU General Public License as published by the Free     
// Software Foundation; either version 2 or (at your option) any later      
// version.                                                                 
//
// eCos is distributed in the hope that it will be useful, but WITHOUT      
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
// for more details.                                                        
//
// You should have received a copy of the GNU General Public License        
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
//
// As a special exception, if other files instantiate templates or use      
// macros or inline functions from this file, or you compile this file      
// and link it with other works to produce a work based on this file,       
// this file does not by itself cause the resulting work to be covered by   
// the GNU General Public License. However the source code for this file    
// must still be made available in accordance with section (3) of the GNU   
// General Public License v2.                                               
//
// This exception does not invalidate any other reasons why a work based    
// on this file might be covered by the GNU General Public License.         
// -------------------------------------------                              
// ####ECOSGPLCOPYRIGHTEND####                                              
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    jlarmour based on stm3210e by nickg
// Date:         2008-07-30
// Description:
//
//####DESCRIPTIONEND####
//
//========================================================================*/

#include <pkgconf/hal.h>
#include <pkgconf/hal_cortexm.h>
#include <pkgconf/hal_cortexm_stm32.h>
#include <pkgconf/hal_cortexm_stm32_stm32x0g_eval.h>
#ifdef CYGPKG_KERNEL
#include <pkgconf/kernel.h>
#endif

#include CYGHWR_MEMORY_LAYOUT_H         // Memory regions

#include <cyg/infra/diag.h>
#include <cyg/infra/cyg_type.h>
#include <cyg/infra/cyg_trac.h>         // tracing macros
#include <cyg/infra/cyg_ass.h>          // assertion macros

#include <cyg/hal/hal_arch.h>           // HAL header
#include <cyg/hal/hal_intr.h>           // HAL header
#include <cyg/hal/hal_if.h>             // HAL header

//==========================================================================

#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT)
#if (CYGNUM_CALL_IF_TABLE_SIZE > 64)
// We force a compilation error for this fatal condition since run-time asserts
// may not be enabled for the build.
#error "The CALL_IF_TABLE_SIZE pre-allocation in the linker scripts for this platform need to be updated"
#endif
#endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT

//==========================================================================
// System init
//
// This is run to set up the basic system, including GPIO setting,
// clock feeds, power supply, and memory initialization. This code
// runs before the DATA is copied from ROM and the BSS cleared, hence
// it cannot make use of static variables or data tables.

__externC void hal_system_init( void )
{
    CYG_ADDRESS base;

    // Enable peripheral clocks in RCC

    base = CYGHWR_HAL_STM32_RCC;

    // All GPIO ports
    // FIXME: this should be done in variant HAL at point of gpio_set
    HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_RCC_AHB1ENR,
#if defined(CYGHWR_HAL_CORTEXM_STM32_FAMILY_F4) // enable CCM clock
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_CCMDATARAMEN) |
#endif // CYGHWR_HAL_CORTEXM_STM32_FAMILY_F4
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOA) |
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOB) |
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOC) |
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOD) |
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOE) |
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOF) |
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOG) |
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOH) |
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB1ENR_GPIOI) );

    // Enable FSMC
    HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_RCC_AHB3ENR,
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB3ENR_FSMC) );

#if defined(CYG_HAL_STARTUP_ROM) | defined(CYG_HAL_STARTUP_ROMINT) | defined(CYG_HAL_STARTUP_SRAM)

    // Reset FSMC in case it was already enabled. This should set
    // all regs back to default documented values, so we don't need
    // to do any precautionary resets.
    HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_RCC_AHB3RSTR,
                     BIT_(CYGHWR_HAL_STM32_RCC_AHB3ENR_FSMC) );
    // Bring out of reset:
    HAL_WRITE_UINT32(base+CYGHWR_HAL_STM32_RCC_AHB3RSTR, 0 );
#endif

#if defined(CYGHWR_HAL_CORTEXM_STM32X0G_ETH_PHY_CLOCK_MCO)
    // Use HSE clock as the MCO1 clock signals for PHY
    {
        cyg_uint32 acr;

        HAL_READ_UINT32(base + CYGHWR_HAL_STM32_RCC_CFGR, acr);
        acr |= CYGHWR_HAL_STM32_RCC_CFGR_MCO1_HSE |
            CYGHWR_HAL_STM32_RCC_CFGR_MCO1PRE_1;
        HAL_WRITE_UINT32(base + CYGHWR_HAL_STM32_RCC_CFGR, acr);
    }
#endif

    // Set all unused GPIO lines to input with pull down to prevent
    // them floating and annoying any external hardware.

    // GPIO Ports C..I reset GPIOx_MODER to 0x00000000
    // GPIO Ports A..I reset GPIOx_OTYPER to 0x00000000
    // CPIO Ports A,C..I reset GPIOx_OSPEEDR to 0x00000000
    // GPIO Ports C..I reset GPIOx_PUPDR to 0x00000000

    // GPIO Port A resets GPIOA_MODER to 0xA8000000
    // GPIO Port A resets GPIOA_PUPDR to 0x64000000
    // GPIO Port A keeps the default JTAG pins on PA13,14,15
    base = CYGHWR_HAL_STM32_GPIOA;
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0x02AAAAAA );

    // GPIO Port B resets GPIOB_MODER to 0x00000280
    // GPIO Port B resets GPIOB_OSPEEDR to 0x000000C0
    // GPIO Port B resets GPIOB_PUPDR to 0x00000100
    // GPIO Port B keeps the default JTAG pins on PB3,4
    base = CYGHWR_HAL_STM32_GPIOB;
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0xAAAAA82A );

    // GPIO Port C - setup PC7 for LED4 as GPIO out, RS232 (USART4) on PC10,11.
    // Rest stay default, with pulldowns on all except PC14,15 (OSC32)
    // just in case that is important.

    base = CYGHWR_HAL_STM32_GPIOC;
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRH, 0x00008800 );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0x0A0A2AAA );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0x00A04000 );

    // GPIO Port D - setup FSMC for SRAM (PD0-1,3-15) and MicroSDcard (PD2) alternate functions
    base = CYGHWR_HAL_STM32_GPIOD;
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRL, 0xCCCCCCCC );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRH, 0xCCCCCCCC );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0xAAAAAAAA );
    // TODO:CONSIDER: OSPEEDR for SRAM pins to 100MHz

    // GPIO Port E - setup FSMC alternate function. PE0-1,3-4,7-15.
    // But not PE5 (A21), PE6(A22), PE2(A23) which are not connected to SRAM.
    base = CYGHWR_HAL_STM32_GPIOE;
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRL, 0xC00CC0CC );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRH, 0xCCCCCCCC );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0x00002820 );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0xAAAA828A );
    // TODO:CONSIDER: OSPEEDR for SRAM pins to 100MHz

    // GPIO Port F - setup FSMC alternate function. PF0-5,12-15.
    // But not PF6-11 which aren't connected to SRAM.
    base = CYGHWR_HAL_STM32_GPIOF;
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRL, 0x00CCCCCC );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRH, 0xCCCC0000 );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0x00AAA000 );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0xAA000AAA );
    // TODO:CONSIDER: OSPEEDR for SRAM pins to 100MHz

    // GPIO Port G - setup FSMC alternate function. PG0-5,9,10.
    // Other FSMC pins not connected to SRAM.
    // LED1 is PG6, LED2 is PG8, so set as GPIO out.
    base = CYGHWR_HAL_STM32_GPIOG;
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRL, 0x00CCCCCC );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_AFRH, 0x00000CC0 );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0xAA808000 );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0x00291AAA );
    // TODO:CONSIDER: OSPEEDR for SRAM pins to 100MHz

    // GPIO Port H stays default, with pulldowns on all except PH0,1 (OSC) just in case that is important.
    base = CYGHWR_HAL_STM32_GPIOH;
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0xAAAAAAA0 );

    // GPIO Port I - setup PI9 for LED3 as GPIO out, rest stay default, with pulldowns
    base = CYGHWR_HAL_STM32_GPIOI;
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_PUPDR, 0xAAA2AAAA );
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_GPIO_MODER, 0x00040000 );


    // Set up FSMC NOR/SRAM bank 2 for SRAM

    base = CYGHWR_HAL_STM32_FSMC;


#if defined(CYGHWR_HAL_CORTEXM_STM32_FAMILY_F4)
    // NOTEs:
    // - The "STM32 20-21-45-46 G-EVAL" boards we have are populated with the
    //   IS61WV102416BLL-10MLI part and not the Cypress CY7C1071DV33 part.
    // - The F4[01][57]xx devices can operate upto 168MHz (or 144MHz) so maximum HCLK
    //   timing of 6ns (or 6.94444ns).
    //
    // NOTE: The code does NOT set BWTR2 for SRAM write-cycle timing (so will be
    // the default reset value of 0x0FFFFFFF) since BCRx:EXTMOD bit is NOT set.

    // TODO:IMPROVE: Derive values based on CLK settings. The following "fixed"
    // values are based on a 168MHz SYSCLK:

    // BCR2 = MBKEN | MWID=0b01 (16bits) | WREN
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BCR2, 0x00001015 );

    // BTR2:
    //   ADDSET=3 (3 HCLK cycles)
    //   ADDHLD=0 (SRAM:do not care)
    //   DATAST=6 (6 HCLK cycles)
    //   BUSTURN=1 (1 HCLK cycle)
    //   CLKDIV=0 (SRAM:do not care)
    //   DATLAT=0 (SRAM:do not care)
    //   ACCMOD=0 (access mode A)
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR2, 0x00010603 );
#else // CYGHWR_HAL_CORTEXM_STM32_FAMILY_F2
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BCR2, 0x00001011 );
    // SRAM timings for the fitted CY7C1071DV33-12BAXI async SRAM
    // We could try and make this depend on hclk as it should, but that's
    // probably overkill for now. With an hclk of 120MHz, each hclk period
    // is 8.33ns, so we just use that. This might mean being slightly
    // suboptimal at lower configured hclk speeds.
    // It's tricky to get the waveforms in the STM32 FSMC docs and the SRAM
    // datasheet, to match up, so there's a small amount of guess work involved
    // here. From the SRAM datasheet, ADDSET should be at least 7ns (tHZWE), and
    // DATAST should be at least 9ns (tPWE) plus one HCLK (from Fig 397 in FSMC
    // docs showing Mode 1 write accesses). This gives ADDSET=1 and
    // DATAST=3.
    HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FSMC_BTR2, 0x00000301 );
#endif // CYGHWR_HAL_CORTEXM_STM32_FAMILY_F2

    // Enable flash prefetch buffer, cacheability and set latency to 2 wait states.
    // Latency has to be set before clock is switched to a higher speed.
    {
        cyg_uint32 acr;

        base = CYGHWR_HAL_STM32_FLASH;

        HAL_READ_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr );
        acr |= CYGHWR_HAL_STM32_FLASH_ACR_PRFTEN;
        acr |= CYGHWR_HAL_STM32_FLASH_ACR_DCEN|CYGHWR_HAL_STM32_FLASH_ACR_ICEN;
        acr |= CYGHWR_HAL_STM32_FLASH_ACR_LATENCY(CYGNUM_HAL_CORTEXM_STM32_FLASH_WAIT_STATES);
        HAL_WRITE_UINT32( base+CYGHWR_HAL_STM32_FLASH_ACR, acr );
    }
}

//==========================================================================

// Set LEDs 1-4 to lowest 4 bits of supplied char.
__externC void hal_stm32x0_led(char c)
{
    CYGHWR_HAL_STM32_GPIO_OUT( CYGHWR_HAL_STM32X0G_LED1, 0 != (c&1) );
    CYGHWR_HAL_STM32_GPIO_OUT( CYGHWR_HAL_STM32X0G_LED2, 0 != (c&2) );
    CYGHWR_HAL_STM32_GPIO_OUT( CYGHWR_HAL_STM32X0G_LED3, 0 != (c&4) );
    CYGHWR_HAL_STM32_GPIO_OUT( CYGHWR_HAL_STM32X0G_LED4, 0 != (c&8) );
}

//==========================================================================

__externC void hal_platform_init( void )
{
#ifdef CYGDBG_USE_ASSERTS
    __externC char __sram_data_start[];
#endif

#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
    // Check the number of VSRs matches the linker script. We can do this
    // because we intend the VV table to follow the VSR table with no gaps.
    CYG_ASSERT( (char*)&hal_virtual_vector_table[0] - (char*)&hal_vsr_table >= CYGNUM_HAL_VSR_COUNT*4,
                "VSR table size does not match" );
    // Now check the declared start of SRAM data follows the VV table end
    CYG_ASSERT( (__sram_data_start - (char*)&hal_virtual_vector_table[0]) >= CYGNUM_CALL_IF_TABLE_SIZE*4,
                "VV table size does not match sram space" );
#else
    // Check the VSR table fits below declared start of SRAM data
    CYG_ASSERT( (__sram_data_start - (char*)&hal_vsr_table[0]) >= CYGNUM_HAL_VSR_COUNT*4,
                "VSR table size does not match" );
#endif
    hal_stm32x0_led(1);
}

//==========================================================================

#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS

//--------------------------------------------------------------------------
// Accesses to areas not backed by real devices or memory can cause
// the CPU to hang.
//
// The following table defines the memory areas that GDB is allowed to
// touch. All others are disallowed.
// This table needs to be kept up to date with the set of memory areas
// that are available on the board.

static struct
{
    CYG_ADDRESS         start;          // Region start address
    CYG_ADDRESS         end;            // End address (last byte)
} hal_data_access[] =
{
    { CYGMEM_REGION_ram,        CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE-1      },      // External SRAM
#ifdef CYGMEM_REGION_sram
    { CYGMEM_REGION_sram,       CYGMEM_REGION_sram+CYGMEM_REGION_sram_SIZE-1    },      // On-chip SRAM
#endif
#ifdef CYGMEM_REGION_flash
    { CYGMEM_REGION_flash,      CYGMEM_REGION_flash+CYGMEM_REGION_flash_SIZE-1  },      // On-chip flash
#endif
    { 0xE0000000,               0x00000000-1                                    },      // Cortex-M peripherals
    { 0x40000000,               0x60000000-1                                    },      // STM32 peripherals
    { 0xA0000000,               0xA0001000-1                                    },      // FSMC control
#ifdef CYGMEM_REGION_ccm
    { CYGMEM_REGION_ccm,        CYGMEM_REGION_ccm+CYGMEM_REGION_ccm_SIZE-1      },      // On-chip (close-coupled) SRAM
#endif
};

__externC int cyg_hal_stub_permit_data_access( CYG_ADDRESS addr, cyg_uint32 count )
{
    int i;
    for( i = 0; i < sizeof(hal_data_access)/sizeof(hal_data_access[0]); i++ )
    {
        if( (addr >= hal_data_access[i].start) &&
            (addr+count) <= hal_data_access[i].end)
            return true;
    }
    return false;
}

#endif // CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS

//==========================================================================

#ifdef CYGPKG_REDBOOT
#include <redboot.h>
#include CYGHWR_MEMORY_LAYOUT_H

//--------------------------------------------------------------------------
// Memory layout
//
// We report the on-chip SRAM and external SRAM.


void
cyg_plf_memory_segment(int seg, unsigned char **start, unsigned char **end)
{
    switch (seg) {
    case 0:
        *start = (unsigned char *)CYGMEM_REGION_ram;
        *end = (unsigned char *)(CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE);
        break;
#ifdef CYGMEM_REGION_sram
    case 1:
        *start = (unsigned char *)CYGMEM_REGION_sram;
        *end = (unsigned char *)(CYGMEM_REGION_sram + CYGMEM_REGION_sram_SIZE);
        break;
#elif defined(CYGMEM_REGION_xram)
    case 1:
        *start = (unsigned char *)CYGMEM_REGION_xram;
        *end = (unsigned char *)(CYGMEM_REGION_xram + CYGMEM_REGION_xram_SIZE);
        break;
#endif
#ifdef CYGMEM_REGION_ccm
    case 2:
        *start = (unsigned char *)CYGMEM_REGION_ccm;
        *end = (unsigned char *)(CYGMEM_REGION_ccm + CYGMEM_REGION_ccm_SIZE);
        break;
#endif
    default:
        *start = *end = NO_MEMORY;
        break;
    }
} // cyg_plf_memory_segment()

#endif // CYGPKG_REDBOOT


//==========================================================================
// EOF stm32x0g_eval_misc.c