Support package for Radioddity GD77

replace/204d151fd90605d0239d8a94bd2da7e083a0a7aa
Silvano Seva 2020-12-01 09:40:50 +01:00 zatwierdzone przez Fred
rodzic 774468ae46
commit eaaaca648b
12 zmienionych plików z 17166 dodań i 5 usunięć

Wyświetl plik

@ -12,10 +12,11 @@ project('OpenRTX', 'c',
## OpenRTX
openrtx_src = ['openrtx/src/bootstrap.c',
'openrtx/src/state.c',
'openrtx/src/ui.c',
'openrtx/src/threads.c']
openrtx_src = ['openrtx/src/bootstrap.c']
#'openrtx/src/state.c',
#'openrtx/src/ui.c',
#'openrtx/src/threads.c']
## Replace main executable with platform test
if get_option('test') != ''
@ -110,6 +111,25 @@ stm32f405_inc = ['platform/mcu/CMSIS/Include',
stm32f405_def = {'STM32F40_41xxx': '', 'HSE_VALUE':'8000000'}
## MK22FN512
mk22fn512_src = ['platform/mcu/MK22FN512xxx12/boot/startup.c',
'platform/mcu/MK22FN512xxx12/boot/libc_integration.c',
'platform/mcu/MK22FN512xxx12/drivers/gpio.c',
'platform/mcu/MK22FN512xxx12/drivers/delays.c',
'platform/mcu/CMSIS/Device/NXP/MK22FN512xxx12/Source/system_MK22F51212.c',
'rtos/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/os_cpu_c.c',
'rtos/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M/os_cpu_a.s',
'rtos/uC-CPU/ARM-Cortex-M/ARMv7-M/cpu_c.c',
'rtos/uC-CPU/ARM-Cortex-M/ARMv7-M/cpu_a.s']
mk22fn512_inc = ['platform/mcu/CMSIS/Include',
'platform/mcu/CMSIS/Device/NXP/MK22FN512xxx12/Include',
'rtos/uC-OS3/Ports/ARM-Cortex-M/ARMv7-M',
'rtos/uC-CPU/ARM-Cortex-M/ARMv7-M']
mk22fn512_def = {}
##
## Platform specializations
##
@ -170,7 +190,6 @@ md390_inc = inc + stm32f405_inc + ['platform/targets/MD-390']
md390_def = def + stm32f405_def + {'PLATFORM_MD390': ''}
## TYT MD-UV380
mduv380_src = src + stm32f405_src + ['platform/drivers/display/HX83XX_MDx.c',
'platform/drivers/keyboard/keyboard_MDx.c',
@ -184,6 +203,13 @@ mduv380_inc = inc + stm32f405_inc + ['platform/targets/MD-UV380']
mduv380_def = def + stm32f405_def + {'PLATFORM_MDUV380': ''}
## Radioddity GD77
gd77_src = src + mk22fn512_src + ['platform/targets/GD77/platform.c']
gd77_inc = inc + mk22fn512_inc + ['platform/targets/GD77']
gd77_def = def + mk22fn512_def + {'PLATFORM_GD77': ''}
##
## Compilation defines
##
@ -231,6 +257,16 @@ foreach k, v : mduv380_def
endif
endforeach
gd77_args = []
foreach k, v : gd77_def
if v == ''
gd77_args += '-D@0@'.format(k)
else
gd77_args += '-D@0@=@1@'.format(k, v)
endif
endforeach
linux_opts = {'sources': linux_src,
'c_args': linux_c_args,
'include_directories': linux_inc,
@ -255,6 +291,12 @@ mduv380_opts = {'sources': mduv380_src,
'-Wl,--print-memory-usage'],
'include_directories': mduv380_inc}
gd77_opts = {'sources': gd77_src,
'c_args': gd77_args,
'link_args' : ['-Wl,-T../platform/mcu/MK22FN512xxx12/linker_script.ld',
'-Wl,--print-memory-usage'],
'include_directories':gd77_inc}
##
## Targets
##
@ -282,6 +324,11 @@ targets = [
'wrap': 'UV3X0',
'load_addr': '0x0800C000'},
{'name': 'gd77',
'opts': gd77_opts,
'flashable': true,
'wrap': 'UV3X0',
'load_addr': '0x0800C000'},
]
objcopy = find_program('objcopy', required:false, disabler:true)

Wyświetl plik

@ -0,0 +1,159 @@
/*
** ###################################################################
** Processors: MK22FN512CAP12
** MK22FN512VDC12
** MK22FN512VFX12
** MK22FN512VLH12
** MK22FN512VLL12
** MK22FN512VMP12
**
** Compilers: Freescale C/C++ for Embedded ARM
** GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
** Keil ARM C/C++ Compiler
** MCUXpresso Compiler
**
** Reference manual: K22P121M120SF7RM, Rev. 1, March 24, 2014
** Version: rev. 2.9, 2016-03-21
** Build: b181105
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2018 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2013-07-23)
** Initial version.
** - rev. 1.1 (2013-09-17)
** RM rev. 0.4 update.
** - rev. 2.0 (2013-10-29)
** Register accessor macros added to the memory map.
** Symbols for Processor Expert memory map compatibility added to the memory map.
** Startup file for gcc has been updated according to CMSIS 3.2.
** System initialization updated.
** - rev. 2.1 (2013-10-30)
** Definition of BITBAND macros updated to support peripherals with 32-bit acces disabled.
** - rev. 2.2 (2013-12-20)
** Update according to reference manual rev. 0.6,
** - rev. 2.3 (2014-01-13)
** Update according to reference manual rev. 0.61,
** - rev. 2.4 (2014-02-10)
** The declaration of clock configurations has been moved to separate header file system_MK22F51212.h
** - rev. 2.5 (2014-05-06)
** Update according to reference manual rev. 1.0,
** Update of system and startup files.
** Module access macro module_BASES replaced by module_BASE_PTRS.
** - rev. 2.6 (2014-08-28)
** Update of system files - default clock configuration changed.
** Update of startup files - possibility to override DefaultISR added.
** - rev. 2.7 (2014-10-14)
** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM.
** - rev. 2.8 (2015-02-19)
** Renamed interrupt vector LLW to LLWU.
** - rev. 2.9 (2016-03-21)
** Added MK22FN512VFX12 part.
** GPIO - renamed port instances: PTx -> GPIOx.
**
** ###################################################################
*/
/*!
* @file MK22F51212
* @version 2.9
* @date 2016-03-21
* @brief Device specific configuration file for MK22F51212 (header file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#ifndef _SYSTEM_MK22F51212_H_
#define _SYSTEM_MK22F51212_H_ /**< Symbol preventing repeated inclusion */
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#ifndef DISABLE_WDOG
#define DISABLE_WDOG 1
#endif
/* Define clock source values */
#define CPU_XTAL_CLK_HZ 8000000u /* Value of the external crystal or oscillator clock frequency in Hz */
#define CPU_XTAL32k_CLK_HZ 32768u /* Value of the external 32k crystal or oscillator clock frequency in Hz */
#define CPU_INT_SLOW_CLK_HZ 32768u /* Value of the slow internal oscillator clock frequency in Hz */
#define CPU_INT_FAST_CLK_HZ 4000000u /* Value of the fast internal oscillator clock frequency in Hz */
#define CPU_INT_IRC_CLK_HZ 48000000u /* Value of the 48M internal oscillator clock frequency in Hz */
/* RTC oscillator setting */
/* RTC_CR: SC2P=0,SC4P=0,SC8P=0,SC16P=0,CLKO=1,OSCE=1,WPS=0,UM=0,SUP=0,WPE=0,SWR=0 */
#define SYSTEM_RTC_CR_VALUE 0x0300U /* RTC_CR */
/* Low power mode enable */
/* SMC_PMPROT: AHSRUN=1,AVLP=1,ALLS=1,AVLLS=1 */
#define SYSTEM_SMC_PMPROT_VALUE 0xAAU /* SMC_PMPROT */
#define DEFAULT_SYSTEM_CLOCK 20971520u /* Default System clock value */
/**
* @brief System clock frequency (core clock)
*
* The system clock frequency supplied to the SysTick timer and the processor
* core clock. This variable can be used by the user application to setup the
* SysTick timer or configure other parameters. It may also be used by debugger to
* query the frequency of the debug timer or configure the trace clock speed
* SystemCoreClock is initialized with a correct predefined value.
*/
extern uint32_t SystemCoreClock;
/**
* @brief Setup the microcontroller system.
*
* Typically this function configures the oscillator (PLL) that is part of the
* microcontroller device. For systems with variable clock speed it also updates
* the variable SystemCoreClock. SystemInit is called from startup_device file.
*/
void SystemInit (void);
/**
* @brief Updates the SystemCoreClock variable.
*
* It must be called whenever the core clock is changed during program
* execution. SystemCoreClockUpdate() evaluates the clock register settings and calculates
* the current core clock.
*/
void SystemCoreClockUpdate (void);
/**
* @brief SystemInit function hook.
*
* This weak function allows to call specific initialization code during the
* SystemInit() execution.This can be used when an application specific code needs
* to be called as close to the reset entry as possible (for example the Multicore
* Manager MCMGR_EarlyInit() function call).
* NOTE: No global r/w variables can be used in this hook function because the
* initialization of these variables happens after this function.
*/
void SystemInitHook (void);
#ifdef __cplusplus
}
#endif
#endif /* _SYSTEM_MK22F51212_H_ */

Wyświetl plik

@ -0,0 +1,243 @@
/*
** ###################################################################
** Processors: MK22FN512CAP12
** MK22FN512VDC12
** MK22FN512VFX12
** MK22FN512VLH12
** MK22FN512VLL12
** MK22FN512VMP12
**
** Compilers: Freescale C/C++ for Embedded ARM
** GNU C Compiler
** IAR ANSI C/C++ Compiler for ARM
** Keil ARM C/C++ Compiler
** MCUXpresso Compiler
**
** Reference manual: K22P121M120SF7RM, Rev. 1, March 24, 2014
** Version: rev. 2.9, 2016-03-21
** Build: b181105
**
** Abstract:
** Provides a system configuration function and a global variable that
** contains the system frequency. It configures the device and initializes
** the oscillator (PLL) that is part of the microcontroller device.
**
** Copyright 2016 Freescale Semiconductor, Inc.
** Copyright 2016-2018 NXP
** All rights reserved.
**
** SPDX-License-Identifier: BSD-3-Clause
**
** http: www.nxp.com
** mail: support@nxp.com
**
** Revisions:
** - rev. 1.0 (2013-07-23)
** Initial version.
** - rev. 1.1 (2013-09-17)
** RM rev. 0.4 update.
** - rev. 2.0 (2013-10-29)
** Register accessor macros added to the memory map.
** Symbols for Processor Expert memory map compatibility added to the memory map.
** Startup file for gcc has been updated according to CMSIS 3.2.
** System initialization updated.
** - rev. 2.1 (2013-10-30)
** Definition of BITBAND macros updated to support peripherals with 32-bit acces disabled.
** - rev. 2.2 (2013-12-20)
** Update according to reference manual rev. 0.6,
** - rev. 2.3 (2014-01-13)
** Update according to reference manual rev. 0.61,
** - rev. 2.4 (2014-02-10)
** The declaration of clock configurations has been moved to separate header file system_MK22F51212.h
** - rev. 2.5 (2014-05-06)
** Update according to reference manual rev. 1.0,
** Update of system and startup files.
** Module access macro module_BASES replaced by module_BASE_PTRS.
** - rev. 2.6 (2014-08-28)
** Update of system files - default clock configuration changed.
** Update of startup files - possibility to override DefaultISR added.
** - rev. 2.7 (2014-10-14)
** Interrupt INT_LPTimer renamed to INT_LPTMR0, interrupt INT_Watchdog renamed to INT_WDOG_EWM.
** - rev. 2.8 (2015-02-19)
** Renamed interrupt vector LLW to LLWU.
** - rev. 2.9 (2016-03-21)
** Added MK22FN512VFX12 part.
** GPIO - renamed port instances: PTx -> GPIOx.
**
** ###################################################################
*/
/*!
* @file MK22F51212
* @version 2.9
* @date 2016-03-21
* @brief Device specific configuration file for MK22F51212 (implementation file)
*
* Provides a system configuration function and a global variable that contains
* the system frequency. It configures the device and initializes the oscillator
* (PLL) that is part of the microcontroller device.
*/
#include <stdint.h>
#include "../Include/MK22F51212.h"
/* ----------------------------------------------------------------------------
-- Core clock
---------------------------------------------------------------------------- */
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
/* Interrupt vectors */
extern uint32_t __Vectors[];
/* ----------------------------------------------------------------------------
-- SystemInit()
---------------------------------------------------------------------------- */
void SystemInit (void) {
SCB->CPACR |= ((3UL << 10*2) | (3UL << 11*2));
#if (DISABLE_WDOG)
/* WDOG->UNLOCK: WDOGUNLOCK=0xC520 */
WDOG->UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xC520); /* Key 1 */
/* WDOG->UNLOCK: WDOGUNLOCK=0xD928 */
WDOG->UNLOCK = WDOG_UNLOCK_WDOGUNLOCK(0xD928); /* Key 2 */
/* WDOG->STCTRLH: ?=0,DISTESTWDOG=0,BYTESEL=0,TESTSEL=0,TESTWDOG=0,?=0,?=1,WAITEN=1,STOPEN=1,DBGEN=0,ALLOWUPDATE=1,WINEN=0,IRQRSTEN=0,CLKSRC=1,WDOGEN=0 */
WDOG->STCTRLH = WDOG_STCTRLH_BYTESEL(0x00) |
WDOG_STCTRLH_WAITEN_MASK |
WDOG_STCTRLH_STOPEN_MASK |
WDOG_STCTRLH_ALLOWUPDATE_MASK |
WDOG_STCTRLH_CLKSRC_MASK |
0x0100U;
#endif
SystemInitHook();
/* Configure the Vector Table location add offset address ------------------*/
SCB->VTOR = (uint32_t)(&__Vectors[0]);
}
/* ----------------------------------------------------------------------------
-- SystemCoreClockUpdate()
---------------------------------------------------------------------------- */
void SystemCoreClockUpdate (void) {
uint32_t MCGOUTClock; /* Variable to store output clock frequency of the MCG module */
uint16_t Divider;
uint8_t tmpC7 = 0;
if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x00U) {
/* Output of FLL or PLL is selected */
if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U) {
/* FLL is selected */
if ((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U) {
/* External reference clock is selected */
switch (MCG->C7 & MCG_C7_OSCSEL_MASK) {
case 0x00U:
MCGOUTClock = CPU_XTAL_CLK_HZ; /* System oscillator drives MCG clock */
break;
case 0x01U:
MCGOUTClock = CPU_XTAL32k_CLK_HZ; /* RTC 32 kHz oscillator drives MCG clock */
break;
case 0x02U:
default:
MCGOUTClock = CPU_INT_IRC_CLK_HZ; /* IRC 48MHz oscillator drives MCG clock */
break;
}
tmpC7 = MCG->C7;
if (((MCG->C2 & MCG_C2_RANGE_MASK) != 0x00U) && ((tmpC7 & MCG_C7_OSCSEL_MASK) != 0x01U)) {
switch (MCG->C1 & MCG_C1_FRDIV_MASK) {
case 0x38U:
Divider = 1536U;
break;
case 0x30U:
Divider = 1280U;
break;
default:
Divider = (uint16_t)(32LU << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT));
break;
}
} else {/* ((MCG->C2 & MCG_C2_RANGE_MASK) != 0x00U) */
Divider = (uint16_t)(1LU << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT));
}
MCGOUTClock = (MCGOUTClock / Divider); /* Calculate the divided FLL reference clock */
} else { /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U)) */
MCGOUTClock = CPU_INT_SLOW_CLK_HZ; /* The slow internal reference clock is selected */
} /* (!((MCG->C1 & MCG_C1_IREFS_MASK) == 0x00U)) */
/* Select correct multiplier to calculate the MCG output clock */
switch (MCG->C4 & (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) {
case 0x00U:
MCGOUTClock *= 640U;
break;
case 0x20U:
MCGOUTClock *= 1280U;
break;
case 0x40U:
MCGOUTClock *= 1920U;
break;
case 0x60U:
MCGOUTClock *= 2560U;
break;
case 0x80U:
MCGOUTClock *= 732U;
break;
case 0xA0U:
MCGOUTClock *= 1464U;
break;
case 0xC0U:
MCGOUTClock *= 2197U;
break;
case 0xE0U:
MCGOUTClock *= 2929U;
break;
default:
MCGOUTClock *= 640U;
break;
}
} else { /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U)) */
/* PLL is selected */
Divider = (((uint16_t)MCG->C5 & MCG_C5_PRDIV0_MASK) + 0x01U);
MCGOUTClock = (uint32_t)(CPU_XTAL_CLK_HZ / Divider); /* Calculate the PLL reference clock */
Divider = (((uint16_t)MCG->C6 & MCG_C6_VDIV0_MASK) + 24U);
MCGOUTClock *= Divider; /* Calculate the MCG output clock */
} /* (!((MCG->C6 & MCG_C6_PLLS_MASK) == 0x00U)) */
} else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x40U) {
/* Internal reference clock is selected */
if ((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U) {
MCGOUTClock = CPU_INT_SLOW_CLK_HZ; /* Slow internal reference clock selected */
} else { /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U)) */
Divider = (uint16_t)(0x01LU << ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT));
MCGOUTClock = (uint32_t) (CPU_INT_FAST_CLK_HZ / Divider); /* Fast internal reference clock selected */
} /* (!((MCG->C2 & MCG_C2_IRCS_MASK) == 0x00U)) */
} else if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U) {
/* External reference clock is selected */
switch (MCG->C7 & MCG_C7_OSCSEL_MASK) {
case 0x00U:
MCGOUTClock = CPU_XTAL_CLK_HZ; /* System oscillator drives MCG clock */
break;
case 0x01U:
MCGOUTClock = CPU_XTAL32k_CLK_HZ; /* RTC 32 kHz oscillator drives MCG clock */
break;
case 0x02U:
default:
MCGOUTClock = CPU_INT_IRC_CLK_HZ; /* IRC 48MHz oscillator drives MCG clock */
break;
}
} else { /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U)) */
/* Reserved value */
return;
} /* (!((MCG->C1 & MCG_C1_CLKS_MASK) == 0x80U)) */
SystemCoreClock = (MCGOUTClock / (0x01U + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT)));
}
/* ----------------------------------------------------------------------------
-- SystemInitHook()
---------------------------------------------------------------------------- */
__attribute__ ((weak)) void SystemInitHook (void) {
/* Void implementation of the weak function. */
}

Wyświetl plik

@ -0,0 +1,437 @@
/***************************************************************************
* Copyright (C) 2020 by Silvano Seva IU2KWO *
* *
* This program 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 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <reent.h>
#include <sys/times.h>
#include <sys/stat.h>
#include <sys/fcntl.h>
#include <unistd.h>
#include <errno.h>
void pthread_mutex_unlock(){}
void pthread_mutex_lock() {}
void pthread_mutex_destroy() {}
int pthread_setcancelstate(int state, int *oldstate)
{
(void) state;
(void) oldstate;
return 0;
}
#ifdef __cplusplus
extern "C" {
#endif
//
// C atexit support, for thread safety and code size optimizations
// ===============================================================
/**
* Function called by atexit(), on_exit() and __cxa_atexit() to register
* C functions/C++ destructors to be run at program termintion.
* It is called in this way:
* atexit(): __register_exitproc(__et_atexit, fn, 0, 0)
* on_exit(): __register_exitproc(__et_onexit, fn, arg, 0)
* __cxa_atexit(): __register_exitproc(__et_cxa, fn, arg, d)
* \param type to understand if the function was called by atexit, on_exit, ...
* \param fn pointer to function to be called
* \param arg 0 in case of atexit, function argument in case of on_exit,
* "this" parameter for C++ destructors registered with __cxa_atexit
* \param d __dso_handle used to selectively call C++ destructors of a shared
* library loaded dynamically, unused since Miosix does not support shared libs
* \return 0 on success
*/
int __register_exitproc(int type, void (*fn)(void), void *arg, void *d)
{
(void) type;
(void) fn;
(void) arg;
(void) d;
return 0;
}
/**
* Called by exit() to call functions registered through atexit()
* \param code the exit code, for example with exit(1), code==1
* \param d __dso_handle, see __register_exitproc
*/
void __call_exitprocs(int code, void *d)
{
(void) code;
(void) d;
}
/**
* \internal
* Required by C++ standard library.
* See http://lists.debian.org/debian-gcc/2003/07/msg00057.html
*/
void *__dso_handle=(void*) &__dso_handle;
//
// C/C++ system calls, to support malloc, printf, fopen, etc.
// ==========================================================
/**
* \internal
* _exit, lock system in infinite loop until reboot
*/
void _exit(int status)
{
(void) status;
for(;;) ;
}
/**
* \internal
* _sbrk_r, allocates memory dynamically
*/
void *_sbrk_r(struct _reent *ptr, ptrdiff_t incr)
{
(void) ptr;
//This is the absolute start of the heap
extern char _end asm("_end"); //defined in the linker script
//This is the absolute end of the heap
extern char _heap_end asm("_heap_end"); //defined in the linker script
//This holds the current end of the heap (static)
static char *curHeapEnd=NULL;
//This holds the previous end of the heap
char *prevHeapEnd;
//Check if it's first time called
if(curHeapEnd==NULL) curHeapEnd=&_end;
prevHeapEnd=curHeapEnd;
if((curHeapEnd+incr)>&_heap_end)
{
return (void*)(-1);
}
curHeapEnd+=incr;
return (void*)(prevHeapEnd);
}
/**
* \internal
* __malloc_lock, called by malloc to ensure no context switch happens during
* memory allocation. Since this environment is not a multithreaded one, this
* function is left empty. Allocating memory inside interrupts is anyway
* forbidden.
*/
void __malloc_lock() {}
/**
* \internal
* __malloc_unlock, called by malloc after performing operations on the heap
*/
void __malloc_unlock() {}
/**
* \internal
* __getreent(), return the reentrancy structure of the current thread.
* Used by newlib to make the C standard library thread safe.
* Not a multithreaded environment, we return global reentrancy data.
*/
struct _reent *__getreent()
{
return _GLOBAL_REENT;
}
/**
* \internal
* _open_r, open a file. Actually unimpemented
*/
int _open_r(struct _reent *ptr, const char *name, int flags, int mode)
{
(void) ptr;
(void) name;
(void) flags;
(void) mode;
return -1;
}
/**
* \internal
* _close_r, close a file. Actually unimpemented
*/
int _close_r(struct _reent *ptr, int fd)
{
(void) ptr;
(void) fd;
return -1;
}
/**
* \internal
* _write_r, write to a file.
*/
int _write_r(struct _reent *ptr, int fd, const void *buf, size_t cnt)
{
if(fd == STDOUT_FILENO || fd == STDERR_FILENO)
{
//vcom_writeBlock(buf, cnt);
//return cnt;
(void) buf;
(void) cnt;
return -1;
}
/* If fd is not stdout or stderr */
ptr->_errno = EBADF;
return -1;
}
/**
* \internal
* _read_r, read from a file.
*/
int _read_r(struct _reent *ptr, int fd, void *buf, size_t cnt)
{
if(fd == STDIN_FILENO)
{
for(;;)
{
//ssize_t r = vcom_readBlock(buf, cnt);
//if((r < 0) || (r == (ssize_t)(cnt))) return r;
(void) buf;
(void) cnt;
return -1;
}
}
else
/* If fd is not stdin */
ptr->_errno = EBADF;
return -1;
}
int _read(int fd, void *buf, size_t cnt)
{
return _read_r(__getreent(), fd, buf, cnt);
}
/**
* \internal
* _lseek_r, move file pointer. Actually unimpemented
*/
off_t _lseek_r(struct _reent *ptr, int fd, off_t pos, int whence)
{
(void) ptr;
(void) fd;
(void) pos;
(void) whence;
return -1;
}
off_t _lseek(int fd, off_t pos, int whence)
{
(void) fd;
(void) pos;
(void) whence;
return -1;
}
/**
* \internal
* _fstat_r, return file info. Actually unimpemented
*/
int _fstat_r(struct _reent *ptr, int fd, struct stat *pstat)
{
(void) ptr;
(void) fd;
(void) pstat;
return -1;
}
int _fstat(int fd, struct stat *pstat)
{
(void) fd;
(void) pstat;
return -1;
}
/**
* \internal
* _stat_r, collect data about a file. Actually unimpemented
*/
int _stat_r(struct _reent *ptr, const char *file, struct stat *pstat)
{
(void) ptr;
(void) file;
(void) pstat;
return -1;
}
/**
* \internal
* isatty, returns 1 if fd is associated with a terminal.
* Always return 1 because read and write are implemented only in
* terms of serial communication
*/
int _isatty_r(struct _reent *ptr, int fd)
{
(void) ptr;
(void) fd;
return 1;
}
int isatty(int fd)
{
(void) fd;
return 1;
}
int _isatty(int fd)
{
(void) fd;
return 1;
}
/**
* \internal
* _mkdir, create a directory. Actually unimpemented
*/
int mkdir(const char *path, mode_t mode)
{
(void) path;
(void) mode;
return -1;
}
/**
* \internal
* _link_r: create hardlinks. Actually unimpemented
*/
int _link_r(struct _reent *ptr, const char *f_old, const char *f_new)
{
(void) ptr;
(void) f_old;
(void) f_new;
return -1;
}
/**
* \internal
* _unlink_r, remove a file. Actually unimpemented
*/
int _unlink_r(struct _reent *ptr, const char *file)
{
(void) ptr;
(void) file;
return -1;
}
/**
* \internal
* _times_r, return elapsed time. Actually unimpemented
*/
clock_t _times_r(struct _reent *ptr, struct tms *tim)
{
(void) ptr;
(void) tim;
return -1;
}
/**
* \internal
* it looks like abort() calls _kill instead of exit, this implementation
* calls _exit() so that calling abort() really terminates the program
*/
int _kill_r(struct _reent* ptr, int pid, int sig)
{
(void) ptr;
(void) sig;
if(pid == 0)
_exit(1);
else
return -1;
}
int _kill(int pid, int sig)
{
return _kill_r(0, pid, sig);
}
/**
* \internal
* _getpid_r. Not a multiprocess system, return always 0
*/
int _getpid_r(struct _reent* ptr)
{
(void) ptr;
return 0;
}
int _getpid()
{
return 0;
}
/**
* \internal
* _wait_r, unimpemented because processes are not supported.
*/
int _wait_r(struct _reent *ptr, int *status)
{
(void) ptr;
(void) status;
return -1;
}
int _fork_r(struct _reent *ptr)
{
(void) ptr;
return -1;
}
#ifdef __cplusplus
}
#endif

Wyświetl plik

@ -0,0 +1,347 @@
/***************************************************************************
* Copyright (C) 2020 by Federico Izzo IU2NUO, Niccolò Izzo IU2KIN and *
* Silvano Seva IU2KWO *
* *
* This program 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 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include <string.h>
#include <stdio.h>
#include "MK22F51212.h"
///< Entry point for system bootstrap after initial configurations.
void systemBootstrap();
void Reset_Handler() __attribute__((__interrupt__, noreturn));
void Reset_Handler()
{
// Disable interrupts at startup, as the RTOS requires this.
__disable_irq();
// Call CMSIS init function, it's safe to do it here.
// This function initialises VTOR, clock-tree and flash memory wait states.
SystemInit();
//These are defined in the linker script
extern unsigned char _etext asm("_etext");
extern unsigned char _data asm("_data");
extern unsigned char _edata asm("_edata");
extern unsigned char _bss_start asm("_bss_start");
extern unsigned char _bss_end asm("_bss_end");
// Initialize .data section, clear .bss section
unsigned char *etext=&_etext;
unsigned char *data=&_data;
unsigned char *edata=&_edata;
unsigned char *bss_start=&_bss_start;
unsigned char *bss_end=&_bss_end;
memcpy(data, etext, edata-data);
memset(bss_start, 0, bss_end-bss_start);
SIM->SCGC5 |= 0x3E00; // Enable GPIO clock
// // Enable virtual com port (for stdin, stdout and stderr redirection)
// vcom_init();
// Set no buffer for stdin, required to make scanf, getchar, ... working
// correctly
setvbuf(stdin, NULL, _IONBF, 0);
// Jump to application code
systemBootstrap();
// If main returns loop indefinitely
for(;;) ;
}
void Default_Handler()
{
// default handler does nothing
}
void __attribute__((weak)) NMI_Handler();
void __attribute__((weak)) HardFault_Handler();
void __attribute__((weak)) MemManage_Handler();
void __attribute__((weak)) BusFault_Handler();
void __attribute__((weak)) UsageFault_Handler();
void __attribute__((weak)) SVC_Handler();
void __attribute__((weak)) DebugMon_Handler();
void __attribute__((weak)) OS_CPU_PendSVHandler(); // uC/OS-III naming convention
void __attribute__((weak)) OS_CPU_SysTickHandler();
void __attribute__((weak)) DMA0_IRQHandler();
void __attribute__((weak)) DMA1_IRQHandler();
void __attribute__((weak)) DMA2_IRQHandler();
void __attribute__((weak)) DMA3_IRQHandler();
void __attribute__((weak)) DMA4_IRQHandler();
void __attribute__((weak)) DMA5_IRQHandler();
void __attribute__((weak)) DMA6_IRQHandler();
void __attribute__((weak)) DMA7_IRQHandler();
void __attribute__((weak)) DMA8_IRQHandler();
void __attribute__((weak)) DMA9_IRQHandler();
void __attribute__((weak)) DMA10_IRQHandler();
void __attribute__((weak)) DMA11_IRQHandler();
void __attribute__((weak)) DMA12_IRQHandler();
void __attribute__((weak)) DMA13_IRQHandler();
void __attribute__((weak)) DMA14_IRQHandler();
void __attribute__((weak)) DMA15_IRQHandler();
void __attribute__((weak)) DMA_Error_IRQHandler();
void __attribute__((weak)) MCM_IRQHandler();
void __attribute__((weak)) FTF_IRQHandler();
void __attribute__((weak)) Read_Collision_IRQHandler();
void __attribute__((weak)) LVD_LVW_IRQHandler();
void __attribute__((weak)) LLWU_IRQHandler();
void __attribute__((weak)) WDOG_EWM_IRQHandler();
void __attribute__((weak)) RNG_IRQHandler();
void __attribute__((weak)) I2C0_IRQHandler();
void __attribute__((weak)) I2C1_IRQHandler();
void __attribute__((weak)) SPI0_IRQHandler();
void __attribute__((weak)) SPI1_IRQHandler();
void __attribute__((weak)) I2S0_Tx_IRQHandler();
void __attribute__((weak)) I2S0_Rx_IRQHandler();
void __attribute__((weak)) LPUART0_IRQHandler();
void __attribute__((weak)) UART0_RX_TX_IRQHandler();
void __attribute__((weak)) UART0_ERR_IRQHandler();
void __attribute__((weak)) UART1_RX_TX_IRQHandler();
void __attribute__((weak)) UART1_ERR_IRQHandler();
void __attribute__((weak)) UART2_RX_TX_IRQHandler();
void __attribute__((weak)) UART2_ERR_IRQHandler();
void __attribute__((weak)) Reserved53_IRQHandler();
void __attribute__((weak)) Reserved54_IRQHandler();
void __attribute__((weak)) ADC0_IRQHandler();
void __attribute__((weak)) CMP0_IRQHandler();
void __attribute__((weak)) CMP1_IRQHandler();
void __attribute__((weak)) FTM0_IRQHandler();
void __attribute__((weak)) FTM1_IRQHandler();
void __attribute__((weak)) FTM2_IRQHandler();
void __attribute__((weak)) Reserved61_IRQHandler();
void __attribute__((weak)) RTC_IRQHandler();
void __attribute__((weak)) RTC_Seconds_IRQHandler();
void __attribute__((weak)) PIT0_IRQHandler();
void __attribute__((weak)) PIT1_IRQHandler();
void __attribute__((weak)) PIT2_IRQHandler();
void __attribute__((weak)) PIT3_IRQHandler();
void __attribute__((weak)) PDB0_IRQHandler();
void __attribute__((weak)) USB0_IRQHandler();
void __attribute__((weak)) Reserved70_IRQHandler();
void __attribute__((weak)) Reserved71_IRQHandler();
void __attribute__((weak)) DAC0_IRQHandler();
void __attribute__((weak)) MCG_IRQHandler();
void __attribute__((weak)) LPTMR0_IRQHandler();
void __attribute__((weak)) PORTA_IRQHandler();
void __attribute__((weak)) PORTB_IRQHandler();
void __attribute__((weak)) PORTC_IRQHandler();
void __attribute__((weak)) PORTD_IRQHandler();
void __attribute__((weak)) PORTE_IRQHandler();
void __attribute__((weak)) SWI_IRQHandler();
void __attribute__((weak)) Reserved81_IRQHandler();
void __attribute__((weak)) Reserved82_IRQHandler();
void __attribute__((weak)) Reserved83_IRQHandler();
void __attribute__((weak)) Reserved84_IRQHandler();
void __attribute__((weak)) Reserved85_IRQHandler();
void __attribute__((weak)) Reserved86_IRQHandler();
void __attribute__((weak)) FTM3_IRQHandler();
void __attribute__((weak)) DAC1_IRQHandler();
void __attribute__((weak)) ADC1_IRQHandler();
//Stack top, defined in the linker script
extern char _stack_top asm("_stack_top");
//Interrupt vectors, must be placed @ address 0x00000000
//The extern declaration is required otherwise g++ optimizes it out
extern void (* const __Vectors[])();
void (* const __Vectors[])() __attribute__ ((section(".isr_vector"))) =
{
(void (*)())(&_stack_top),
Reset_Handler,
NMI_Handler,
HardFault_Handler,
MemManage_Handler,
BusFault_Handler,
UsageFault_Handler,
0,
0,
0,
0,
SVC_Handler,
DebugMon_Handler,
0,
OS_CPU_PendSVHandler,
OS_CPU_SysTickHandler,
DMA0_IRQHandler, /* DMA Channel 0 Transfer Complete*/
DMA1_IRQHandler, /* DMA Channel 1 Transfer Complete*/
DMA2_IRQHandler, /* DMA Channel 2 Transfer Complete*/
DMA3_IRQHandler, /* DMA Channel 3 Transfer Complete*/
DMA4_IRQHandler, /* DMA Channel 4 Transfer Complete*/
DMA5_IRQHandler, /* DMA Channel 5 Transfer Complete*/
DMA6_IRQHandler, /* DMA Channel 6 Transfer Complete*/
DMA7_IRQHandler, /* DMA Channel 7 Transfer Complete*/
DMA8_IRQHandler, /* DMA Channel 8 Transfer Complete*/
DMA9_IRQHandler, /* DMA Channel 9 Transfer Complete*/
DMA10_IRQHandler, /* DMA Channel 10 Transfer Complete*/
DMA11_IRQHandler, /* DMA Channel 11 Transfer Complete*/
DMA12_IRQHandler, /* DMA Channel 12 Transfer Complete*/
DMA13_IRQHandler, /* DMA Channel 13 Transfer Complete*/
DMA14_IRQHandler, /* DMA Channel 14 Transfer Complete*/
DMA15_IRQHandler, /* DMA Channel 15 Transfer Complete*/
DMA_Error_IRQHandler, /* DMA Error Interrupt*/
MCM_IRQHandler, /* Normal Interrupt*/
FTF_IRQHandler, /* FTFA Command complete interrupt*/
Read_Collision_IRQHandler, /* Read Collision Interrupt*/
LVD_LVW_IRQHandler, /* Low Voltage Detect, Low Voltage Warning*/
LLWU_IRQHandler, /* Low Leakage Wakeup Unit*/
WDOG_EWM_IRQHandler, /* WDOG Interrupt*/
RNG_IRQHandler, /* RNG Interrupt*/
I2C0_IRQHandler, /* I2C0 interrupt*/
I2C1_IRQHandler, /* I2C1 interrupt*/
SPI0_IRQHandler, /* SPI0 Interrupt*/
SPI1_IRQHandler, /* SPI1 Interrupt*/
I2S0_Tx_IRQHandler, /* I2S0 transmit interrupt*/
I2S0_Rx_IRQHandler, /* I2S0 receive interrupt*/
LPUART0_IRQHandler, /* LPUART0 status/error interrupt*/
UART0_RX_TX_IRQHandler, /* UART0 Receive/Transmit interrupt*/
UART0_ERR_IRQHandler, /* UART0 Error interrupt*/
UART1_RX_TX_IRQHandler, /* UART1 Receive/Transmit interrupt*/
UART1_ERR_IRQHandler, /* UART1 Error interrupt*/
UART2_RX_TX_IRQHandler, /* UART2 Receive/Transmit interrupt*/
UART2_ERR_IRQHandler, /* UART2 Error interrupt*/
Reserved53_IRQHandler, /* Reserved interrupt 53*/
Reserved54_IRQHandler, /* Reserved interrupt 54*/
ADC0_IRQHandler, /* ADC0 interrupt*/
CMP0_IRQHandler, /* CMP0 interrupt*/
CMP1_IRQHandler, /* CMP1 interrupt*/
FTM0_IRQHandler, /* FTM0 fault, overflow and channels interrupt*/
FTM1_IRQHandler, /* FTM1 fault, overflow and channels interrupt*/
FTM2_IRQHandler, /* FTM2 fault, overflow and channels interrupt*/
Reserved61_IRQHandler, /* Reserved interrupt 61*/
RTC_IRQHandler, /* RTC interrupt*/
RTC_Seconds_IRQHandler, /* RTC seconds interrupt*/
PIT0_IRQHandler, /* PIT timer channel 0 interrupt*/
PIT1_IRQHandler, /* PIT timer channel 1 interrupt*/
PIT2_IRQHandler, /* PIT timer channel 2 interrupt*/
PIT3_IRQHandler, /* PIT timer channel 3 interrupt*/
PDB0_IRQHandler, /* PDB0 Interrupt*/
USB0_IRQHandler, /* USB0 interrupt*/
Reserved70_IRQHandler, /* Reserved interrupt 70*/
Reserved71_IRQHandler, /* Reserved interrupt 71*/
DAC0_IRQHandler, /* DAC0 interrupt*/
MCG_IRQHandler, /* MCG Interrupt*/
LPTMR0_IRQHandler, /* LPTimer interrupt*/
PORTA_IRQHandler, /* Port A interrupt*/
PORTB_IRQHandler, /* Port B interrupt*/
PORTC_IRQHandler, /* Port C interrupt*/
PORTD_IRQHandler, /* Port D interrupt*/
PORTE_IRQHandler, /* Port E interrupt*/
SWI_IRQHandler, /* Software interrupt*/
Reserved81_IRQHandler, /* Reserved interrupt 81*/
Reserved82_IRQHandler, /* Reserved interrupt 82*/
Reserved83_IRQHandler, /* Reserved interrupt 83*/
Reserved84_IRQHandler, /* Reserved interrupt 84*/
Reserved85_IRQHandler, /* Reserved interrupt 85*/
Reserved86_IRQHandler, /* Reserved interrupt 86*/
FTM3_IRQHandler, /* FTM3 fault, overflow and channels interrupt*/
DAC1_IRQHandler, /* DAC1 interrupt*/
ADC1_IRQHandler /* ADC1 interrupt*/
};
#pragma weak NMI_Handler= Default_Handler
#pragma weak HardFault_Handler= Default_Handler
#pragma weak MemManage_Handler= Default_Handler
#pragma weak BusFault_Handler= Default_Handler
#pragma weak UsageFault_Handler= Default_Handler
#pragma weak SVC_Handler= Default_Handler
#pragma weak DebugMon_Handler= Default_Handler
#pragma weak PendSV_Handler= Default_Handler
#pragma weak SysTick_Handler= Default_Handler
#pragma weak WWDG_IRQHandler= Default_Handler
#pragma weak DMA0_IRQHandler = Default_Handler
#pragma weak DMA1_IRQHandler = Default_Handler
#pragma weak DMA2_IRQHandler = Default_Handler
#pragma weak DMA3_IRQHandler = Default_Handler
#pragma weak DMA4_IRQHandler = Default_Handler
#pragma weak DMA5_IRQHandler = Default_Handler
#pragma weak DMA6_IRQHandler = Default_Handler
#pragma weak DMA7_IRQHandler = Default_Handler
#pragma weak DMA8_IRQHandler = Default_Handler
#pragma weak DMA9_IRQHandler = Default_Handler
#pragma weak DMA10_IRQHandler = Default_Handler
#pragma weak DMA11_IRQHandler = Default_Handler
#pragma weak DMA12_IRQHandler = Default_Handler
#pragma weak DMA13_IRQHandler = Default_Handler
#pragma weak DMA14_IRQHandler = Default_Handler
#pragma weak DMA15_IRQHandler = Default_Handler
#pragma weak DMA_Error_IRQHandler = Default_Handler
#pragma weak MCM_IRQHandler = Default_Handler
#pragma weak FTF_IRQHandler = Default_Handler
#pragma weak Read_Collision_IRQHandler = Default_Handler
#pragma weak LVD_LVW_IRQHandler = Default_Handler
#pragma weak LLWU_IRQHandler = Default_Handler
#pragma weak WDOG_EWM_IRQHandler = Default_Handler
#pragma weak RNG_IRQHandler = Default_Handler
#pragma weak I2C0_IRQHandler = Default_Handler
#pragma weak I2C1_IRQHandler = Default_Handler
#pragma weak SPI0_IRQHandler = Default_Handler
#pragma weak SPI1_IRQHandler = Default_Handler
#pragma weak I2S0_Tx_IRQHandler = Default_Handler
#pragma weak I2S0_Rx_IRQHandler = Default_Handler
#pragma weak LPUART0_IRQHandler = Default_Handler
#pragma weak UART0_RX_TX_IRQHandler = Default_Handler
#pragma weak UART0_ERR_IRQHandler = Default_Handler
#pragma weak UART1_RX_TX_IRQHandler = Default_Handler
#pragma weak UART1_ERR_IRQHandler = Default_Handler
#pragma weak UART2_RX_TX_IRQHandler = Default_Handler
#pragma weak UART2_ERR_IRQHandler = Default_Handler
#pragma weak Reserved53_IRQHandler = Default_Handler
#pragma weak Reserved54_IRQHandler = Default_Handler
#pragma weak ADC0_IRQHandler = Default_Handler
#pragma weak CMP0_IRQHandler = Default_Handler
#pragma weak CMP1_IRQHandler = Default_Handler
#pragma weak FTM0_IRQHandler = Default_Handler
#pragma weak FTM1_IRQHandler = Default_Handler
#pragma weak FTM2_IRQHandler = Default_Handler
#pragma weak Reserved61_IRQHandler = Default_Handler
#pragma weak RTC_IRQHandler = Default_Handler
#pragma weak RTC_Seconds_IRQHandler = Default_Handler
#pragma weak PIT0_IRQHandler = Default_Handler
#pragma weak PIT1_IRQHandler = Default_Handler
#pragma weak PIT2_IRQHandler = Default_Handler
#pragma weak PIT3_IRQHandler = Default_Handler
#pragma weak PDB0_IRQHandler = Default_Handler
#pragma weak USB0_IRQHandler = Default_Handler
#pragma weak Reserved70_IRQHandler = Default_Handler
#pragma weak Reserved71_IRQHandler = Default_Handler
#pragma weak DAC0_IRQHandler = Default_Handler
#pragma weak MCG_IRQHandler = Default_Handler
#pragma weak LPTMR0_IRQHandler = Default_Handler
#pragma weak PORTA_IRQHandler = Default_Handler
#pragma weak PORTB_IRQHandler = Default_Handler
#pragma weak PORTC_IRQHandler = Default_Handler
#pragma weak PORTD_IRQHandler = Default_Handler
#pragma weak PORTE_IRQHandler = Default_Handler
#pragma weak SWI_IRQHandler = Default_Handler
#pragma weak Reserved81_IRQHandler = Default_Handler
#pragma weak Reserved82_IRQHandler = Default_Handler
#pragma weak Reserved83_IRQHandler = Default_Handler
#pragma weak Reserved84_IRQHandler = Default_Handler
#pragma weak Reserved85_IRQHandler = Default_Handler
#pragma weak Reserved86_IRQHandler = Default_Handler
#pragma weak FTM3_IRQHandler = Default_Handler
#pragma weak DAC1_IRQHandler = Default_Handler
#pragma weak ADC1_IRQHandler = Default_Handler

Wyświetl plik

@ -0,0 +1,51 @@
/***************************************************************************
* Copyright (C) 2020 by Silvano Seva IU2KWO and Niccolò Izzo IU2KIN *
* *
* This program 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 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include "delays.h"
/**
* Implementation of the delay functions for STM32F405 MCU.
*/
void delayUs(unsigned int useconds)
{
// This delay has been calibrated to take x microseconds
// It is written in assembler to be independent on compiler optimization
asm volatile(" mov r1, #42 \n"
" mul r2, %0, r1 \n"
" mov r1, #0 \n"
"___loop_u: cmp r1, r2 \n"
" itt lo \n"
" addlo r1, r1, #1 \n"
" blo ___loop_u \n"::"r"(useconds):"r1","r2");
}
void delayMs(unsigned int mseconds)
{
register const unsigned int count=42000;
for(unsigned int i=0;i<mseconds;i++)
{
// This delay has been calibrated to take 1 millisecond
// It is written in assembler to be independent on compiler optimization
asm volatile(" mov r1, #0 \n"
"___loop_m: cmp r1, %0 \n"
" itt lo \n"
" addlo r1, r1, #1 \n"
" blo ___loop_m \n"::"r"(count):"r1");
}
}

Wyświetl plik

@ -0,0 +1,176 @@
/***************************************************************************
* Copyright (C) 2020 by Silvano Seva IU2KWO *
* *
* This program 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 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include "MK22F51212.h"
#include "gpio.h"
/*
* MK22 GPIO management is a bit convoluted: instead of having all the registers
* needed for GPIO configuration in one single peripheral (like ST does), we have
* GPIO peripheral for input/output direction selection, output control and
* input reading, while alternate function, pull up/down and other stuff is
* managed by the PORT peripheral. WHY?!
* To overcome this while keeping the GPIO driver interface standard, we have to
* create a function that, given the GPIO register, gives back the corresponding
* PORT one. Ah, and, of course, this cannot be made using simple pointer
* addition/subtraction/multiplication...
*/
PORT_Type *getPortFromGPio(const GPIO_Type *gpio)
{
PORT_Type *port;
switch(((unsigned int) gpio))
{
case ((unsigned int) GPIOA):
port = PORTA;
break;
case ((unsigned int) GPIOB):
port = PORTB;
break;
case ((unsigned int) GPIOC):
port = PORTC;
break;
case ((unsigned int) GPIOD):
port = PORTD;
break;
case ((unsigned int) GPIOE):
port = PORTE;
break;
default:
port = 0;
break;
}
return port;
}
void gpio_setMode(void *port, uint8_t pin, enum Mode mode)
{
GPIO_Type *g = (GPIO_Type *)(port);
PORT_Type *p = getPortFromGPio(g);
/* Clear previous settings */
g->PDDR &= ~(1 << pin);
p->PCR[pin] = 0;
switch(mode)
{
case INPUT:
p->PCR[pin] |= PORT_PCR_MUX(1); /* Enable pin in GPIO mode */
g->PDDR &= ~(1 << pin); /* Input mode */
break;
case INPUT_PULL_UP:
p->PCR[pin] |= PORT_PCR_MUX(1); /* Enable pin in GPIO mode */
p->PCR[pin] |= PORT_PCR_PS(1); /* Pull up mode */
p->PCR[pin] |= PORT_PCR_PE(1); /* Pull up/down enable */
g->PDDR &= ~(1 << pin); /* Input mode */
break;
case INPUT_PULL_DOWN:
p->PCR[pin] |= PORT_PCR_MUX(1); /* Enable pin in GPIO mode */
p->PCR[pin] &= ~PORT_PCR_PS(1); /* Pull down mode */
p->PCR[pin] |= PORT_PCR_PE(1); /* Pull up/down enable */
g->PDDR &= ~(1 << pin); /* Input mode */
break;
/*
* case INPUT_ANALOG:
* NOTE: analog input mode unimplemented here for hardware structure
* reasons.
*/
case OUTPUT:
p->PCR[pin] |= PORT_PCR_MUX(1); /* Enable pin in GPIO mode */
g->PDDR |= (1 << pin); /* Output mode */
break;
case OPEN_DRAIN:
p->PCR[pin] |= PORT_PCR_MUX(1); /* Enable pin in GPIO mode */
p->PCR[pin] |= PORT_PCR_ODE(1); /* Enable open drain mode */
g->PDDR |= (1 << pin); /* Output mode */
break;
/*
* case ALTERNATE:
* NOTE: alternate mode unimplemented here for hardware structure
* reasons.
*/
/*
* ALTERNATE_OD:
* NOTE: alternate open drain mode unimplemented here for hardware
* structure reasons.
*/
default:
p->PCR[pin] |= PORT_PCR_MUX(1); /* Enable pin in GPIO mode */
g->PDDR &= ~(1 << pin); /* Input mode */
break;
}
}
void gpio_setAlternateFunction(void *port, uint8_t pin, uint8_t afNum)
{
GPIO_Type *g = (GPIO_Type *)(port);
PORT_Type *p = getPortFromGPio(g);
p->PCR[pin] &= ~PORT_PCR_MUX_MASK; /* Clear old configuration */
p->PCR[pin] |= PORT_PCR_MUX(2 + afNum); /* Set new AF, range 0 - 7 */
}
void gpio_setOutputSpeed(void *port, uint8_t pin, enum Speed spd)
{
GPIO_Type *g = (GPIO_Type *)(port);
PORT_Type *p = getPortFromGPio(g);
if(spd >= FAST)
{
p->PCR[pin] |= PORT_PCR_SRE(1);
}
else
{
p->PCR[pin] &= ~PORT_PCR_SRE(1);
}
}
void gpio_setPin(void *port, uint8_t pin)
{
((GPIO_Type *)(port))->PSOR = (1 << pin);
}
void gpio_clearPin(void *port, uint8_t pin)
{
((GPIO_Type *)(port))->PCOR = (1 << pin);
}
void gpio_togglePin(void *port, uint8_t pin)
{
((GPIO_Type *)(port))->PTOR ^= (1 << pin);
}
uint8_t gpio_readPin(const void *port, uint8_t pin)
{
GPIO_Type *g = (GPIO_Type *)(port);
return ((g->PDIR & (1 << pin)) != 0) ? 1 : 0;
}

Wyświetl plik

@ -0,0 +1,131 @@
/*
RAM space is organized in this way: the stack begins at the end of
the RAM space and grows down towards the base, while the heap begins
at the end of the bss space (symbol _end) and grows up towards the
end of the RAM.
WARNING: with this configuration we have an high risk of collision
between stack and heap, since none of them is limited. One thing to
do in the future is to put this limit to the stack.
*/
_stack_top = 0x20010000;
/* temporary set heap end equal to stack top */
_heap_end = _stack_top;
/* identify the Entry Point */
ENTRY(Reset_Handler)
/* specify the memory areas */
MEMORY
{
flash(rx) : ORIGIN = 0x4000, LENGTH = 0x7B800
ram(wx) : ORIGIN = 0x1FFF0000, LENGTH = 128K
}
/* now define the output sections */
SECTIONS
{
. = 0;
/* .text section: code goes to flash */
.text :
{
/* Startup code must go at address 0 */
KEEP(*(.isr_vector))
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
/* these sections for thumb interwork? */
*(.glue_7)
*(.glue_7t)
/* these sections for C++? */
*(.gcc_except_table)
*(.gcc_except_table.*)
*(.ARM.extab*)
*(.gnu.linkonce.armextab.*)
. = ALIGN(4);
/* .rodata: constant data */
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
/* C++ Static constructors/destructors (eabi) */
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
/* C++ Static constructors/destructors (elf) */
. = ALIGN(4);
_ctor_start = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
_ctor_end = .;
. = ALIGN(4);
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
} > flash
/* .ARM.exidx is sorted, so has to go in its own output section. */
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > flash
__exidx_end = .;
/* .data section: global variables go to ram, but also store a copy to
flash to initialize them */
.data : ALIGN(8)
{
_data = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
_edata = .;
} > ram AT > flash
_etext = LOADADDR(.data);
/* .bss section: uninitialized global variables go to ram */
.bss :
{
_bss_start = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
. = ALIGN(8);
} > ram
_bss_end = .;
_end = .;
PROVIDE(end = .);
}

Wyświetl plik

@ -0,0 +1,30 @@
/***************************************************************************
* Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, *
* Niccolò Izzo IU2KIN *
* Frederik Saraci IU2NRO *
* Silvano Seva IU2KWO *
* *
* This program 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 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#ifndef HWCONFIG_H
#define HWCONFIG_H
#include "MK22F51212.h"
/* Signalling LEDs */
#define GREEN_LED GPIOB,18
#define RED_LED GPIOC,14
#endif

Wyświetl plik

@ -0,0 +1,115 @@
/***************************************************************************
* Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, *
* Niccolò Izzo IU2KIN *
* Frederik Saraci IU2NRO *
* Silvano Seva IU2KWO *
* *
* This program 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 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include <platform.h>
#include <gpio.h>
#include "hwconfig.h"
void platform_init()
{
/* Configure GPIOs */
gpio_setMode(GREEN_LED, OUTPUT);
gpio_setMode(RED_LED, OUTPUT);
}
void platform_terminate()
{
/* TODO */
}
float platform_getVbat()
{
/* TODO */
return 0.0f;
}
float platform_getMicLevel()
{
/* TODO */
return 0.0f;
}
float platform_getVolumeLevel()
{
/* TODO */
return 0.0f;
}
uint8_t platform_getChSelector()
{
/* TODO */
return 0;
}
bool platform_getPttStatus()
{
/* TODO */
return false;
}
void platform_ledOn(led_t led)
{
switch(led)
{
case GREEN:
gpio_setPin(GREEN_LED);
break;
case RED:
gpio_setPin(RED_LED);
break;
default:
break;
}
}
void platform_ledOff(led_t led)
{
switch(led)
{
case GREEN:
gpio_clearPin(GREEN_LED);
break;
case RED:
gpio_clearPin(RED_LED);
break;
default:
break;
}
}
void platform_beepStart(uint16_t freq)
{
/* TODO */
(void) freq;
}
void platform_beepStop()
{
/* TODO */
}
void platform_setBacklightLevel(uint8_t level)
{
/* TODO */
}

Wyświetl plik

@ -0,0 +1,40 @@
/***************************************************************************
* Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, *
* Niccolò Izzo IU2KIN, *
* Frederik Saraci IU2NRO, *
* Silvano Seva IU2KWO *
* *
* This program 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 3 of the License, or *
* (at your option) any later version. *
* *
* This program 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 this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include <os.h>
#include <stdio.h>
#include <platform.h>
int main()
{
platform_init();
while(1)
{
OS_ERR e;
platform_ledOn(GREEN);
OSTimeDlyHMSM(0u, 0u, 1u, 0u, OS_OPT_TIME_HMSM_STRICT, &e);
platform_ledOff(GREEN);
OSTimeDlyHMSM(0u, 0u, 1u, 0u, OS_OPT_TIME_HMSM_STRICT, &e);
}
return 0;
}