mirror of
https://github.com/mist-devel/mist-firmware.git
synced 2026-01-11 23:43:04 +00:00
Move HW specific parts to hw/
This commit is contained in:
parent
9ce37feebf
commit
9193f06134
@ -9,9 +9,8 @@
|
||||
|
||||
#include "ff.h" /* Obtains integer types */
|
||||
#include "diskio.h" /* Declarations of disk functions */
|
||||
#include "usb.h"
|
||||
#include "usbrtc.h"
|
||||
#include "../mmc.h"
|
||||
#include "hardware.h"
|
||||
#include "mmc.h"
|
||||
|
||||
/* Definitions of physical drive number for each drive */
|
||||
#define DEV_MMC 0
|
||||
@ -213,7 +212,7 @@ DWORD get_fattime()
|
||||
uint8_t date[7]; //year,month,date,hour,min,sec,day
|
||||
DWORD fattime = ((DWORD)(FF_NORTC_YEAR - 1980) << 25 | (DWORD)FF_NORTC_MON << 21 | (DWORD)FF_NORTC_MDAY << 16);
|
||||
|
||||
if (usb_rtc_get_time((uint8_t*)&date)) {
|
||||
if (GetRTC((uint8_t*)&date)) {
|
||||
fattime = ((date[0] - 80) << 25) |
|
||||
((date[1] & 0x0f) << 21) |
|
||||
((date[2] & 0x1f) << 16) |
|
||||
|
||||
24
Makefile
24
Makefile
@ -10,25 +10,25 @@ DUMP = $(BASE)-objdump
|
||||
TODAY = `date +"%m/%d/%y"`
|
||||
|
||||
PRJ = firmware
|
||||
SRC = Cstartup_SAM7.c fdd.c firmware.c fpga.c hardware.c spi.c hdd.c main.c menu.c mmc.c osd.c state.c syscalls.c user_io.c data_io.c boot.c idxfile.c config.c tos.c ikbd.c xmodem.c ini_parser.c cue_parser.c mist_cfg.c archie.c pcecd.c arc_file.c font.c utils.c
|
||||
SRC = hw/AT91SAM/Cstartup_SAM7.c hw/AT91SAM/hardware.c hw/AT91SAM/spi.c hw/AT91SAM/mmc.c hw/AT91SAM/cdc_enumerate.c
|
||||
SRC += fdd.c firmware.c fpga.c hdd.c main.c menu.c osd.c state.c syscalls.c user_io.c data_io.c boot.c idxfile.c config.c tos.c ikbd.c xmodem.c ini_parser.c cue_parser.c mist_cfg.c archie.c pcecd.c arc_file.c font.c utils.c
|
||||
SRC += usb/max3421e.c usb/usb.c usb/hub.c usb/hid.c usb/hidparser.c usb/timer.c usb/asix.c usb/pl2303.c usb/usbrtc.c usb/joymapping.c
|
||||
SRC += fat_compat.c
|
||||
SRC += FatFs/diskio.c FatFs/ff.c FatFs/ffunicode.c
|
||||
# SRC += usb/storage.c
|
||||
SRC += cdc_enumerate.c cdc_control.c
|
||||
SRC += cdc_control.c
|
||||
|
||||
OBJ = $(SRC:.c=.o)
|
||||
DEP = $(SRC:.c=.d)
|
||||
|
||||
LINKMAP = AT91SAM7S256-ROM.ld
|
||||
LINKMAP = hw/AT91SAM/AT91SAM7S256-ROM.ld
|
||||
LIBDIR =
|
||||
|
||||
# Commandline options for each tool.
|
||||
# for ESA11 add -DEMIST
|
||||
DFLAGS = -I. -Iusb -DMIST
|
||||
CFLAGS = $(DFLAGS) -c -mthumb -fno-common -O2 --std=gnu99 -fsigned-char -DVDATE=\"`date +"%y%m%d"`\"
|
||||
DFLAGS = -I. -Iusb -Iarch/ -Ihw/AT91SAM -DMIST -DCONFIG_ARCH_ARMV4TE -DCONFIG_ARCH_ARM
|
||||
CFLAGS = $(DFLAGS) -c -march=armv4t -mtune=arm7tdmi -mthumb -fno-common -O2 --std=gnu99 -fsigned-char -DVDATE=\"`date +"%y%m%d"`\"
|
||||
CFLAGS-firmware.o += -marm
|
||||
CFLAGS-spi.o += -marm
|
||||
CFLAGS += $(CFLAGS-$@)
|
||||
AFLAGS = -ahls -mapcs-32
|
||||
LFLAGS = -mthumb -nostartfiles -Wl,-Map,$(PRJ).map -T$(LINKMAP) $(LIBDIR)
|
||||
@ -43,7 +43,7 @@ LIBS =
|
||||
all: $(PRJ).hex $(PRJ).upg
|
||||
|
||||
clean:
|
||||
rm -f *.d *.o *.hex *.elf *.map *.lst core *~ */*.d */*.o $(MKUPG) *.bin *.upg *.exe
|
||||
rm -f *.d *.o *.hex *.elf *.map *.lst core *~ */*.d */*.o */*/*.d */*/*.o $(MKUPG) *.bin *.upg *.exe
|
||||
|
||||
INTERFACE=interface/ftdi/olimex-arm-usb-tiny-h.cfg
|
||||
#INTERFACE=interface/busblaster.cfg
|
||||
@ -51,13 +51,17 @@ INTERFACE=interface/ftdi/olimex-arm-usb-tiny-h.cfg
|
||||
ADAPTER_KHZ=10000
|
||||
|
||||
reset:
|
||||
openocd -f $(INTERFACE) -f target/at91sam7sx.cfg --command "adapter_khz $(ADAPTER_KHZ); init; reset init; resume; shutdown"
|
||||
openocd -f $(INTERFACE) -f target/at91sam7sx.cfg --command "adapter speed $(ADAPTER_KHZ); init; reset init; resume; shutdown"
|
||||
|
||||
$(MKUPG): $(MKUPG).c
|
||||
gcc -o $@ $<
|
||||
|
||||
debug: $(PRJ).hex $(PRJ).upg $(PRJ).bin
|
||||
openocd -f $(INTERFACE) -f target/at91sam7sx.cfg --command 'adapter speed $(ADAPTER_KHZ); init; reset init; resume; \
|
||||
echo "*********************"; echo "Start GDB debug session with:"; echo "> gdb $(PRJ).elf"; echo "(gdb) target ext:3333"; echo "*********************"'
|
||||
|
||||
flash: $(PRJ).hex $(PRJ).upg $(PRJ).bin
|
||||
openocd -f $(INTERFACE) -f target/at91sam7sx.cfg --command "adapter_khz $(ADAPTER_KHZ); init; reset init; flash protect 0 0 7 off; sleep 1; arm7_9 fast_memory_access enable; flash write_bank 0 $(PRJ).bin 0x0; resume; shutdown"
|
||||
openocd -f $(INTERFACE) -f target/at91sam7sx.cfg --command "adapter speed $(ADAPTER_KHZ); init; reset init; flash protect 0 0 7 off; sleep 1; arm7_9 fast_memory_access enable; flash write_bank 0 $(PRJ).bin 0x0; resume; shutdown"
|
||||
|
||||
flash_sam: $(PRJ).hex
|
||||
Sam_I_Am -x flash_sam_i_am
|
||||
@ -78,7 +82,7 @@ $(PRJ).upg: $(PRJ).bin $(MKUPG)
|
||||
./$(MKUPG) $< $@ `date +"%y%m%d"`
|
||||
|
||||
# Compile the C runtime.
|
||||
crt.o: Cstartup.S
|
||||
crt.o: hw/AT91SAM/Cstartup.S
|
||||
$(AS) $(AFLAGS) -o $@ $< > crt.lst
|
||||
|
||||
%.o: %.c
|
||||
|
||||
73
arch/arm/barriers.h
Normal file
73
arch/arm/barriers.h
Normal file
@ -0,0 +1,73 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef ARM_BARRIERS_H_
|
||||
#define ARM_BARRIERS_H_
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Public functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_ARCH_ARMV5TE)
|
||||
|
||||
static inline void dmb(void)
|
||||
{
|
||||
asm("" ::: "memory");
|
||||
}
|
||||
|
||||
static inline void dsb(void)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c7, c10, 4" :: "r"(0) : "memory");
|
||||
}
|
||||
|
||||
static inline void isb(void)
|
||||
{
|
||||
asm("" ::: "memory");
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_ARCH_ARMV7A) || defined(CONFIG_ARCH_ARMV7M)
|
||||
|
||||
static inline void dmb(void)
|
||||
{
|
||||
asm("dmb" ::: "memory");
|
||||
}
|
||||
|
||||
static inline void dsb(void)
|
||||
{
|
||||
asm("dsb" ::: "memory");
|
||||
}
|
||||
|
||||
static inline void isb(void)
|
||||
{
|
||||
asm("isb" ::: "memory");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ARM_BARRIERS_H_ */
|
||||
222
arch/arm/cp15.h
Normal file
222
arch/arm/cp15.h
Normal file
@ -0,0 +1,222 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef CP15_H_
|
||||
#define CP15_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/* SCTLR: I - I-cache enable/disable
|
||||
* 0 = I-cache disabled
|
||||
* 1 = I-cache enabled
|
||||
*/
|
||||
#define CP15_SCTLR_I (1u << 12)
|
||||
|
||||
/* SCTLR: C - D-cache enable/disable
|
||||
* 0 = D-cache disabled
|
||||
* 1 = D-cache enabled
|
||||
*/
|
||||
#define CP15_SCTLR_C (1u << 2)
|
||||
|
||||
/* SCTLR: A - Alignment fault enable/disable
|
||||
* 0 = Data address alignment fault checking disabled
|
||||
* 1 = Data address alignment fault checking enabled
|
||||
*/
|
||||
#define CP15_SCTLR_A (1u << 1)
|
||||
|
||||
/* SCTLR: M - MMU enable/disable
|
||||
* 0 = disabled
|
||||
* 1 = enabled
|
||||
*/
|
||||
#define CP15_SCTLR_M (1u << 0)
|
||||
|
||||
/* ACTLR: EXCL - Exclusive L1/L2 cache control.
|
||||
* 0 = non-exclusive
|
||||
* 1 = exclusive
|
||||
*/
|
||||
#define CP15_ACTLR_EXCL (1u << 7)
|
||||
|
||||
/* No access: Any access generates a domain fault. */
|
||||
#define CP15_DACR_NO_ACCESS(x) (0u << (2 * ((x) & 15)))
|
||||
|
||||
/* Client: Accesses are checked against the access permission bits in the
|
||||
* section or page descriptor. */
|
||||
#define CP15_DACR_CLIENT_ACCESS(x) (1u << (2 * ((x) & 15)))
|
||||
|
||||
/* Manager: Accesses are not checked against the access permission bits so a
|
||||
* permission fault cannot be generated. */
|
||||
#define CP15_DACR_MANAGER_ACCESS(x) (3u << (2 * ((x) & 15)))
|
||||
|
||||
/*------------------------------------------------------------------------------ */
|
||||
/* Exported functions */
|
||||
/*------------------------------------------------------------------------------ */
|
||||
|
||||
/**
|
||||
* \brief Read the System Control Register (SCTLR).
|
||||
* \return register contents
|
||||
*/
|
||||
static inline uint32_t cp15_read_sctlr(void)
|
||||
{
|
||||
uint32_t sctlr;
|
||||
asm("mrc p15, 0, %0, c1, c0, 0" : "=r"(sctlr));
|
||||
return sctlr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Modify the System Control Register (SCTLR).
|
||||
* \param value new value for SCTLR
|
||||
*/
|
||||
static inline void cp15_write_sctlr(uint32_t value)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c1, c0, 0" :: "r"(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read the Auxiliary Control Register (ACTLR).
|
||||
* \return register contents
|
||||
*/
|
||||
static inline uint32_t cp15_read_actlr(void)
|
||||
{
|
||||
uint32_t actlr;
|
||||
asm("mrc p15, 0, %0, c1, c0, 1" : "=r"(actlr));
|
||||
return actlr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Modify the Auxiliary Control Register (ACTLR).
|
||||
* \param value new value for ACTLR
|
||||
*/
|
||||
static inline void cp15_write_actlr(uint32_t value)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c1, c0, 1" :: "r"(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read the Translation Table Base Register 0 (TTBR0).
|
||||
* \return register contents
|
||||
*/
|
||||
static inline uint32_t cp15_read_ttbr0(uint32_t value)
|
||||
{
|
||||
uint32_t ttbr0;
|
||||
asm("mrc p15, 0, %0, c2, c0, 0" : "=r"(ttbr0));
|
||||
return ttbr0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write the Translation Table Base Register 0 (TTBR0).
|
||||
* \param value new value for TTBR0
|
||||
*/
|
||||
static inline void cp15_write_ttbr0(uint32_t value)
|
||||
{
|
||||
/* write TTBR */
|
||||
asm("mcr p15, 0, %0, c2, c0, 0" :: "r"(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read the Domain Access Control Register (DACR).
|
||||
* \return register contents
|
||||
*/
|
||||
static inline uint32_t cp15_read_dacr(void)
|
||||
{
|
||||
uint32_t dacr;
|
||||
asm("mrc p15, 0, %0, c3, c0, 0" : "=r"(dacr));
|
||||
return dacr;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Modify the Domain Access Control Register (DACR).
|
||||
* \param value new value for DACR
|
||||
*/
|
||||
static inline void cp15_write_dacr(uint32_t value)
|
||||
{
|
||||
/* write DACR */
|
||||
asm("mcr p15, 0, %0, c3, c0, 0" :: "r"(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief ICIALLU: Invalidate I-cache
|
||||
*/
|
||||
static inline void cp15_icache_invalidate(void)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c7, c5, 0" :: "r"(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief DCISW - Invalidate DCache single entry (Set/Way)
|
||||
*/
|
||||
static inline void cp15_dcache_invalidate_setway(uint32_t setway)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c7, c6, 2" :: "r"(setway));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief DCCSW: Clean DCache single entry (Set/Way)
|
||||
*/
|
||||
static inline void cp15_dcache_clean_setway(uint32_t setway)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c7, c10, 2" :: "r"(setway));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief DCCISW - Clean and invalidate DCache entry (Set/Way)
|
||||
*/
|
||||
static inline void cp15_dcache_clean_invalidate_setway(uint32_t setway)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c7, c14, 2" :: "r"(setway));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief DCIMVAC - Invalidate DCache single entry (MVA)
|
||||
*/
|
||||
static inline void cp15_dcache_invalidate_mva(uint32_t mva)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c7, c6, 1" :: "r"(mva));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief DCCMVAC - Clean DCache single entry (MVA)
|
||||
*/
|
||||
static inline void cp15_dcache_clean_mva(uint32_t mva)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c7, c10, 1" :: "r"(mva));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief DCCIMVAC - Clean and invalidate DCache entry (MVA)
|
||||
*/
|
||||
static inline void cp15_dcache_clean_invalidate_mva(uint32_t mva)
|
||||
{
|
||||
asm("mcr p15, 0, %0, c7, c14, 1" :: "r"(mva));
|
||||
}
|
||||
|
||||
#endif /* CP15_H_ */
|
||||
64
arch/arm/cpuidle.h
Normal file
64
arch/arm/cpuidle.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef ARM_CPUIDLE_H_
|
||||
#define ARM_CPUIDLE_H_
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Public functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_ARCH_ARMV5TE)
|
||||
|
||||
static inline void cpu_idle(void)
|
||||
{
|
||||
/* drain write buffer */
|
||||
asm("mcr p15, 0, %0, c7, c10, 4" :: "r"(0) : "memory");
|
||||
/* wait for interrupt */
|
||||
asm("mcr p15, 0, %0, c7, c0, 4" :: "r"(0) : "memory");
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_ARCH_ARMV7A)
|
||||
|
||||
static inline void cpu_idle(void)
|
||||
{
|
||||
asm("dsb" ::: "memory");
|
||||
asm("wfi" ::: "memory");
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_ARCH_ARMV7M)
|
||||
|
||||
static inline void cpu_idle(void)
|
||||
{
|
||||
asm("wfi" ::: "memory");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ARM_CPUIDLE_H_ */
|
||||
195
arch/arm/fault_handlers.c
Normal file
195
arch/arm/fault_handlers.c
Normal file
@ -0,0 +1,195 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2015, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "arm/fault_handlers.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Constants
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef CONFIG_HAVE_FAULT_DEBUG
|
||||
|
||||
/* IFSR status */
|
||||
static const char* _prefetch_abort_status[32] = {
|
||||
NULL,
|
||||
NULL,
|
||||
"debug event",
|
||||
"access flag fault, section",
|
||||
NULL,
|
||||
"translation fault, section",
|
||||
"access flag fault, page",
|
||||
"translation fault, page",
|
||||
"synchronous external abort",
|
||||
"domain fault, section",
|
||||
NULL,
|
||||
"domain fault, page",
|
||||
"L1 translation, synchronous external abort",
|
||||
"permission fault, section",
|
||||
"L2 translation, synchronous external abort",
|
||||
"permission fault, page",
|
||||
};
|
||||
|
||||
/* DFSR status */
|
||||
static const char* _data_abort_status[32] = {
|
||||
NULL,
|
||||
"alignment fault",
|
||||
"debug event",
|
||||
"access flag fault, section",
|
||||
"instruction cache maintenance fault",
|
||||
"translation fault, section",
|
||||
"access flag fault, page",
|
||||
"translation fault, page",
|
||||
"synchronous external abort, nontranslation",
|
||||
"domain fault, section",
|
||||
NULL,
|
||||
"domain fault, page",
|
||||
"1st level translation, synchronous external abort",
|
||||
"permission fault, section",
|
||||
"2nd level translation, synchronous external abort",
|
||||
"permission fault, page",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"asynchronous external abort"
|
||||
};
|
||||
|
||||
#endif /* CONFIG_HAVE_FAULT_DEBUG */
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Default handler for "Undefined Instruction" exception
|
||||
*/
|
||||
void undefined_instruction_irq_handler(void)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_FAULT_DEBUG
|
||||
printf("\r\n");
|
||||
printf("#####################\r\n");
|
||||
printf("Undefined Instruction\r\n");
|
||||
printf("#####################\r\n");
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
asm("bkpt #1");
|
||||
#endif
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Default handler for "Software Interrupt" exception
|
||||
*/
|
||||
void software_interrupt_irq_handler(void)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_FAULT_DEBUG
|
||||
printf("\r\n");
|
||||
printf("##################\r\n");
|
||||
printf("Software Interrupt\r\n");
|
||||
printf("##################\r\n");
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
asm("bkpt #2");
|
||||
#endif
|
||||
while(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Default handler for "Data Abort" exception
|
||||
*/
|
||||
void data_abort_irq_handler(void)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_FAULT_DEBUG
|
||||
uint32_t v1, v2, dfsr;
|
||||
|
||||
asm("mrc p15, 0, %0, c5, c0, 0" : "=r"(v1));
|
||||
asm("mrc p15, 0, %0, c6, c0, 0" : "=r"(v2));
|
||||
|
||||
printf("\r\n");
|
||||
printf("####################\r\n");
|
||||
dfsr = ((v1 >> 4) & 0x0F);
|
||||
printf("Data Fault occured in %x domain\r\n", (unsigned int)dfsr);
|
||||
dfsr = (((v1 & 0x400) >> 6) | (v1 & 0x0F));
|
||||
if (_data_abort_status[dfsr])
|
||||
printf("Data Fault reason is: %s\r\n", _data_abort_status[dfsr]);
|
||||
else
|
||||
printf("Data Fault reason is unknown\r\n");
|
||||
printf("Data Fault occured at address: 0x%08x\r\n", (unsigned int)v2);
|
||||
printf("Data Fault status register value: 0x%x\r\n", (unsigned int)v1);
|
||||
printf("####################\n\r");
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
asm("bkpt #4");
|
||||
#endif
|
||||
#ifdef CONFIG_HAVE_FAULT_DEBUG
|
||||
while(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Default handler for "Prefetch Abort" exception
|
||||
*/
|
||||
void prefetch_abort_irq_handler(void)
|
||||
{
|
||||
#ifdef CONFIG_HAVE_FAULT_DEBUG
|
||||
uint32_t v1, v2, ifsr;
|
||||
|
||||
asm("mrc p15, 0, %0, c5, c0, 1" : "=r"(v1));
|
||||
asm("mrc p15, 0, %0, c6, c0, 2" : "=r"(v2));
|
||||
|
||||
printf("\r\n");
|
||||
printf("####################\r\n");
|
||||
ifsr = (((v1 & 0x400) >> 6) | (v1 & 0x0F));
|
||||
if (_prefetch_abort_status[ifsr])
|
||||
printf("Prefetch Fault reason is: %s\r\n", _prefetch_abort_status[ifsr]);
|
||||
else
|
||||
printf("Prefetch Fault reason is unknown\r\n");
|
||||
printf("prefetch Fault occured at address: 0x%08x\r\n", (unsigned int)v2);
|
||||
printf("Prefetch Fault status register value: 0x%x\r\n", (unsigned int)v1);
|
||||
printf("####################\n\r");
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
asm("bkpt #3");
|
||||
#endif
|
||||
while(1);
|
||||
}
|
||||
49
arch/arm/fault_handlers.h
Normal file
49
arch/arm/fault_handlers.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2015, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* ARM core interrupt handlers
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ARM_FAULT_HANDLERS_H
|
||||
#define ARM_FAULT_HANDLERS_H
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
extern void undefined_instruction_irq_handler(void);
|
||||
extern void software_interrupt_irq_handler(void);
|
||||
extern void prefetch_abort_irq_handler(void);
|
||||
extern void data_abort_irq_handler(void);
|
||||
|
||||
#endif /* ARM_FAULT_HANDLERS_H */
|
||||
85
arch/arm/irqflags.h
Normal file
85
arch/arm/irqflags.h
Normal file
@ -0,0 +1,85 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef ARM_IRQFLAGS_H_
|
||||
#define ARM_IRQFLAGS_H_
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Public functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_ARCH_ARMV5TE) || defined(CONFIG_ARCH_ARMV4TE)
|
||||
|
||||
static inline void arch_irq_enable(void)
|
||||
{
|
||||
uint32_t cpsr;
|
||||
asm("mrs %0, cpsr" : "=r"(cpsr));
|
||||
asm("msr cpsr_c, %0" :: "r"(cpsr & ~0x80));
|
||||
}
|
||||
|
||||
static inline void arch_irq_disable(void)
|
||||
{
|
||||
uint32_t cpsr;
|
||||
asm("mrs %0, cpsr" : "=r"(cpsr));
|
||||
asm("msr cpsr_c, %0" :: "r"(cpsr | 0x80));
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_ARCH_ARMV7A)
|
||||
|
||||
static inline void arch_irq_enable(void)
|
||||
{
|
||||
asm("cpsie if");
|
||||
}
|
||||
|
||||
static inline void arch_irq_disable(void)
|
||||
{
|
||||
asm("cpsid if");
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_ARCH_ARMV7M)
|
||||
|
||||
static inline void arch_irq_enable(void)
|
||||
{
|
||||
asm("cpsie i");
|
||||
}
|
||||
|
||||
static inline void arch_irq_disable(void)
|
||||
{
|
||||
asm("cpsid i");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ARM_IRQFLAGS_H_ */
|
||||
187
arch/arm/l1cache_cp15.c
Normal file
187
arch/arm/l1cache_cp15.c
Normal file
@ -0,0 +1,187 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2015-2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* L1 Cache functions implementation for ARMv5-TE and ARMv7-A
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "chip.h"
|
||||
#include "barriers.h"
|
||||
|
||||
#include "arm/cp15.h"
|
||||
|
||||
#include "l1cache.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Global functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
void icache_invalidate(void)
|
||||
{
|
||||
cp15_icache_invalidate();
|
||||
isb();
|
||||
}
|
||||
|
||||
bool icache_is_enabled(void)
|
||||
{
|
||||
return (cp15_read_sctlr() & CP15_SCTLR_I) != 0;
|
||||
}
|
||||
|
||||
void icache_enable(void)
|
||||
{
|
||||
uint32_t sctlr = cp15_read_sctlr();
|
||||
if ((sctlr & CP15_SCTLR_I) == 0) {
|
||||
icache_invalidate();
|
||||
cp15_write_sctlr(sctlr | CP15_SCTLR_I);
|
||||
}
|
||||
}
|
||||
|
||||
void icache_disable(void)
|
||||
{
|
||||
uint32_t sctlr = cp15_read_sctlr();
|
||||
if (sctlr & CP15_SCTLR_I) {
|
||||
cp15_write_sctlr(sctlr & ~CP15_SCTLR_I);
|
||||
icache_invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
bool dcache_is_enabled(void)
|
||||
{
|
||||
return (cp15_read_sctlr() & (CP15_SCTLR_C | CP15_SCTLR_M)) ==
|
||||
(CP15_SCTLR_C | CP15_SCTLR_M);
|
||||
}
|
||||
|
||||
void dcache_enable(void)
|
||||
{
|
||||
uint32_t sctlr = cp15_read_sctlr();
|
||||
if ((sctlr & CP15_SCTLR_C) == 0) {
|
||||
assert(sctlr & CP15_SCTLR_M);
|
||||
dcache_invalidate();
|
||||
cp15_write_sctlr(sctlr | CP15_SCTLR_C);
|
||||
}
|
||||
}
|
||||
|
||||
void dcache_disable(void)
|
||||
{
|
||||
uint32_t sctlr = cp15_read_sctlr();
|
||||
if (sctlr & CP15_SCTLR_C) {
|
||||
dcache_clean();
|
||||
cp15_write_sctlr(sctlr & ~CP15_SCTLR_C);
|
||||
dcache_invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void dcache_invalidate(void)
|
||||
{
|
||||
uint32_t set, way;
|
||||
|
||||
for (way = 0; way < L1_CACHE_WAYS; way++)
|
||||
for (set = 0; set < L1_CACHE_SETS; set++)
|
||||
cp15_dcache_invalidate_setway(L1_CACHE_SETWAY(set, way));
|
||||
|
||||
dsb();
|
||||
}
|
||||
|
||||
void dcache_clean(void)
|
||||
{
|
||||
uint32_t set, way;
|
||||
|
||||
for (way = 0; way < L1_CACHE_WAYS; way++)
|
||||
for (set = 0; set < L1_CACHE_SETS; set++)
|
||||
cp15_dcache_clean_setway(L1_CACHE_SETWAY(set, way));
|
||||
|
||||
dsb();
|
||||
}
|
||||
|
||||
void dcache_clean_invalidate(void)
|
||||
{
|
||||
uint32_t set, way;
|
||||
|
||||
for (way = 0; way < L1_CACHE_WAYS; way++)
|
||||
for (set = 0; set < L1_CACHE_SETS; set++)
|
||||
cp15_dcache_clean_invalidate_setway(L1_CACHE_SETWAY(set, way));
|
||||
|
||||
dsb();
|
||||
}
|
||||
|
||||
void dcache_invalidate_region(uint32_t start, uint32_t end)
|
||||
{
|
||||
uint32_t mva;
|
||||
|
||||
assert(start < end);
|
||||
|
||||
for (mva = start & ~(L1_CACHE_BYTES - 1); mva < end; mva += L1_CACHE_BYTES)
|
||||
cp15_dcache_invalidate_mva(mva);
|
||||
|
||||
dsb();
|
||||
}
|
||||
|
||||
void dcache_clean_region(uint32_t start, uint32_t end)
|
||||
{
|
||||
uint32_t mva;
|
||||
|
||||
assert(start < end);
|
||||
|
||||
for (mva = start & ~(L1_CACHE_BYTES - 1); mva < end; mva += L1_CACHE_BYTES)
|
||||
cp15_dcache_clean_mva(mva);
|
||||
|
||||
dsb();
|
||||
}
|
||||
|
||||
void dcache_clean_invalidate_region(uint32_t start, uint32_t end)
|
||||
{
|
||||
uint32_t mva;
|
||||
|
||||
assert(start < end);
|
||||
|
||||
for (mva = start & ~(L1_CACHE_BYTES - 1); mva < end; mva += L1_CACHE_BYTES)
|
||||
cp15_dcache_clean_invalidate_mva(mva);
|
||||
|
||||
dsb();
|
||||
}
|
||||
|
||||
void dcache_set_exclusive(void)
|
||||
{
|
||||
uint32_t actlr = cp15_read_actlr();
|
||||
actlr |= CP15_ACTLR_EXCL;
|
||||
cp15_write_actlr(actlr);
|
||||
}
|
||||
|
||||
void dcache_set_non_exclusive(void)
|
||||
{
|
||||
uint32_t actlr = cp15_read_actlr();
|
||||
actlr &= ~CP15_ACTLR_EXCL;
|
||||
cp15_write_actlr(actlr);
|
||||
}
|
||||
190
arch/arm/l1cache_scb.c
Normal file
190
arch/arm/l1cache_scb.c
Normal file
@ -0,0 +1,190 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2015-2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
* L1 Cache functions implementation for ARMv7-M
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "chip.h"
|
||||
#include "barriers.h"
|
||||
|
||||
#include "l1cache.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Global functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
void icache_invalidate(void)
|
||||
{
|
||||
dsb();
|
||||
isb();
|
||||
SCB->SCB_ICIALLU = 0;
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
|
||||
bool icache_is_enabled(void)
|
||||
{
|
||||
return (SCB->SCB_CCR & SCB_CCR_IC) != 0;
|
||||
}
|
||||
|
||||
void icache_enable(void)
|
||||
{
|
||||
if (!icache_is_enabled()) {
|
||||
icache_invalidate();
|
||||
SCB->SCB_CCR |= SCB_CCR_IC;
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
}
|
||||
|
||||
void icache_disable(void)
|
||||
{
|
||||
if (icache_is_enabled()) {
|
||||
dsb();
|
||||
isb();
|
||||
SCB->SCB_CCR &= ~SCB_CCR_IC;
|
||||
icache_invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
bool dcache_is_enabled(void)
|
||||
{
|
||||
return (SCB->SCB_CCR & SCB_CCR_DC) != 0;
|
||||
}
|
||||
|
||||
void dcache_enable(void)
|
||||
{
|
||||
if (!dcache_is_enabled()) {
|
||||
dcache_invalidate();
|
||||
SCB->SCB_CCR |= SCB_CCR_DC;
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
}
|
||||
|
||||
void dcache_disable(void)
|
||||
{
|
||||
if (dcache_is_enabled()) {
|
||||
dsb();
|
||||
SCB->SCB_CCR &= ~SCB_CCR_DC;
|
||||
dcache_clean_invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
void dcache_invalidate(void)
|
||||
{
|
||||
uint32_t set, way;
|
||||
|
||||
for (way = 0; way < L1_CACHE_WAYS; way++)
|
||||
for (set = 0; set < L1_CACHE_SETS; set++)
|
||||
SCB->SCB_DCISW = L1_CACHE_SETWAY(set, way);
|
||||
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
|
||||
void dcache_clean(void)
|
||||
{
|
||||
uint32_t set, way;
|
||||
|
||||
for (way = 0; way < L1_CACHE_WAYS; way++)
|
||||
for (set = 0; set < L1_CACHE_SETS; set++)
|
||||
SCB->SCB_DCCSW = L1_CACHE_SETWAY(set, way);
|
||||
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
|
||||
void dcache_clean_invalidate(void)
|
||||
{
|
||||
uint32_t set, way;
|
||||
|
||||
for (way = 0; way < L1_CACHE_WAYS; way++)
|
||||
for (set = 0; set < L1_CACHE_SETS; set++)
|
||||
SCB->SCB_DCCISW = L1_CACHE_SETWAY(set, way);
|
||||
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
|
||||
void dcache_invalidate_region(uint32_t start, uint32_t end)
|
||||
{
|
||||
uint32_t mva;
|
||||
|
||||
assert(start < end);
|
||||
|
||||
for (mva = start & ~(L1_CACHE_BYTES - 1); mva < end; mva += L1_CACHE_BYTES)
|
||||
SCB->SCB_DCIMVAC = mva;
|
||||
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
|
||||
void dcache_clean_region(uint32_t start, uint32_t end)
|
||||
{
|
||||
uint32_t mva;
|
||||
|
||||
assert(start < end);
|
||||
|
||||
for (mva = start & ~(L1_CACHE_BYTES - 1); mva < end; mva += L1_CACHE_BYTES)
|
||||
SCB->SCB_DCCMVAC = mva;
|
||||
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
|
||||
void dcache_clean_invalidate_region(uint32_t start, uint32_t end)
|
||||
{
|
||||
uint32_t mva;
|
||||
|
||||
assert(start < end);
|
||||
|
||||
for (mva = start & ~(L1_CACHE_BYTES - 1); mva < end; mva += L1_CACHE_BYTES)
|
||||
SCB->SCB_DCCIMVAC = mva;
|
||||
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
|
||||
void dcache_set_exclusive(void)
|
||||
{
|
||||
/* Not implemented */
|
||||
}
|
||||
|
||||
void dcache_set_non_exclusive(void)
|
||||
{
|
||||
/* Not implemented */
|
||||
}
|
||||
89
arch/arm/mmu_cp15.c
Normal file
89
arch/arm/mmu_cp15.c
Normal file
@ -0,0 +1,89 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2015, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------ */
|
||||
/* Headers */
|
||||
/*------------------------------------------------------------------------------ */
|
||||
|
||||
#include "compiler.h"
|
||||
#include "barriers.h"
|
||||
|
||||
#include "arm/cp15.h"
|
||||
#include "arm/mmu_cp15.h"
|
||||
|
||||
#include "mm/l1cache.h"
|
||||
#include "mm/mmu.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/*------------------------------------------------------------------------------ */
|
||||
/* Exported functions */
|
||||
/*------------------------------------------------------------------------------ */
|
||||
|
||||
void mmu_configure(void *tlb)
|
||||
{
|
||||
assert(!mmu_is_enabled());
|
||||
|
||||
/* Translation Table Base Register 0 */
|
||||
cp15_write_ttbr0((unsigned int)tlb);
|
||||
|
||||
/* Domain Access Register */
|
||||
/* only domain 15: access are not checked */
|
||||
cp15_write_dacr(0xC0000000);
|
||||
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
|
||||
bool mmu_is_enabled(void)
|
||||
{
|
||||
return (cp15_read_sctlr() & CP15_SCTLR_M) != 0;
|
||||
}
|
||||
|
||||
void mmu_enable(void)
|
||||
{
|
||||
uint32_t control;
|
||||
|
||||
control = cp15_read_sctlr();
|
||||
if ((control & CP15_SCTLR_M) == 0)
|
||||
cp15_write_sctlr(control | CP15_SCTLR_M);
|
||||
}
|
||||
|
||||
void mmu_disable(void)
|
||||
{
|
||||
uint32_t control;
|
||||
|
||||
control = cp15_read_sctlr();
|
||||
if (control & CP15_SCTLR_M) {
|
||||
dcache_clean();
|
||||
control &= ~(CP15_SCTLR_M | CP15_SCTLR_C);
|
||||
cp15_write_sctlr(control);
|
||||
dcache_invalidate();
|
||||
}
|
||||
}
|
||||
93
arch/arm/mmu_cp15.h
Normal file
93
arch/arm/mmu_cp15.h
Normal file
@ -0,0 +1,93 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2015, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef MMU_CP15_H_
|
||||
#define MMU_CP15_H_
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mm/mmu.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/* TTB descriptor type for Section descriptor */
|
||||
#define TTB_TYPE_SECT (2 << 0)
|
||||
|
||||
/* TTB Section Descriptor: Buffered/Non-Buffered (B) */
|
||||
#define TTB_SECT_WRITE_THROUGH (0 << 2)
|
||||
#define TTB_SECT_WRITE_BACK (1 << 2)
|
||||
|
||||
/* TTB Section Descriptor: Cacheable/Non-Cacheable (C) */
|
||||
#define TTB_SECT_NON_CACHEABLE (0 << 3)
|
||||
#define TTB_SECT_CACHEABLE (1 << 3)
|
||||
|
||||
#define TTB_SECT_STRONGLY_ORDERED (TTB_SECT_NON_CACHEABLE | TTB_SECT_WRITE_THROUGH)
|
||||
#define TTB_SECT_SHAREABLE_DEVICE (TTB_SECT_NON_CACHEABLE | TTB_SECT_WRITE_BACK)
|
||||
#define TTB_SECT_CACHEABLE_WT (TTB_SECT_CACHEABLE | TTB_SECT_WRITE_THROUGH)
|
||||
#define TTB_SECT_CACHEABLE_WB (TTB_SECT_CACHEABLE | TTB_SECT_WRITE_BACK)
|
||||
|
||||
/* TTB Section Descriptor: Domain */
|
||||
#define TTB_SECT_DOMAIN(x) (((x) & 15) << 5)
|
||||
|
||||
#if defined(CONFIG_ARCH_ARMV5TE)
|
||||
|
||||
/* TTB Section Descriptor: Should-Be-One (SBO) */
|
||||
#define TTB_SECT_SBO (1 << 4)
|
||||
|
||||
/* TTB Section Descriptor: Access Privilege (AP) */
|
||||
#define TTB_SECT_AP_PRIV_ONLY (1 << 10)
|
||||
#define TTB_SECT_AP_NO_USER_WRITE (2 << 10)
|
||||
#define TTB_SECT_AP_FULL_ACCESS (3 << 10)
|
||||
|
||||
#elif defined(CONFIG_ARCH_ARMV7A)
|
||||
|
||||
/* TTB Section Descriptor: Execute/Execute-Never (XN) */
|
||||
#define TTB_SECT_EXEC (0 << 4)
|
||||
#define TTB_SECT_EXEC_NEVER (1 << 4)
|
||||
|
||||
/* TTB Section Descriptor: Access Privilege (AP) */
|
||||
#define TTB_SECT_AP_PRIV_ONLY ((0 << 15) | (1 << 10))
|
||||
#define TTB_SECT_AP_NO_USER_WRITE ((0 << 15) | (2 << 10))
|
||||
#define TTB_SECT_AP_FULL_ACCESS ((0 << 15) | (3 << 10))
|
||||
#define TTB_SECT_AP_PRIV_READ_ONLY ((1 << 15) | (1 << 10))
|
||||
#define TTB_SECT_AP_READ_ONLY ((1 << 15) | (2 << 10))
|
||||
|
||||
#endif /* CONFIG_ARCH_* */
|
||||
|
||||
/* TTB Section Descriptor: Section Base Address */
|
||||
#define TTB_SECT_ADDR(x) ((x) & 0xFFF00000)
|
||||
|
||||
#endif /* MMU_CP15_H_ */
|
||||
77
arch/arm/mpu_armv7m.c
Normal file
77
arch/arm/mpu_armv7m.c
Normal file
@ -0,0 +1,77 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------ */
|
||||
/* Headers */
|
||||
/*------------------------------------------------------------------------------ */
|
||||
|
||||
#include "chip.h"
|
||||
#include "barriers.h"
|
||||
|
||||
#include "arm/mpu_armv7m.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/*------------------------------------------------------------------------------ */
|
||||
/* Exported functions */
|
||||
/*------------------------------------------------------------------------------ */
|
||||
|
||||
void mpu_configure(const void* config)
|
||||
{
|
||||
uint32_t* values = (uint32_t*)config;
|
||||
|
||||
while (*values != 0) {
|
||||
MPU->MPU_REGION[0].MPU_RBAR = *values++;
|
||||
MPU->MPU_REGION[0].MPU_RASR = *values++;
|
||||
}
|
||||
}
|
||||
|
||||
bool mpu_is_enabled(void)
|
||||
{
|
||||
return (MPU->MPU_CTRL & MPU_CTRL_ENABLE) != 0;
|
||||
}
|
||||
|
||||
void mpu_enable(void)
|
||||
{
|
||||
/* Activate MemFault, BusFault & UsageFault exceptions */
|
||||
SCB->SCB_SHCSR |= (SCB_SHCSR_MEMFAULTENA |
|
||||
SCB_SHCSR_BUSFAULTENA |
|
||||
SCB_SHCSR_USGFAULTENA);
|
||||
|
||||
/* Enable the MPU without the background region */
|
||||
MPU->MPU_CTRL = MPU_CTRL_ENABLE;
|
||||
|
||||
dsb();
|
||||
isb();
|
||||
}
|
||||
|
||||
void mpu_disable(void)
|
||||
{
|
||||
MPU->MPU_CTRL = 0;
|
||||
}
|
||||
102
arch/arm/mpu_armv7m.h
Normal file
102
arch/arm/mpu_armv7m.h
Normal file
@ -0,0 +1,102 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef MPU_ARMV7M_H_
|
||||
#define MPU_ARMV7M_H_
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mm/mpu.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/* Region Address and Index */
|
||||
#define MPU_REGION(region, addr) (((addr) & MPU_RBAR_ADDR_Msk) |\
|
||||
MPU_RBAR_REGION(region) | MPU_RBAR_VALID)
|
||||
|
||||
/* Region Sizes: region size is 2^(value+1)*/
|
||||
#define MPU_REGION_SIZE(value) (MPU_RASR_SIZE(value))
|
||||
|
||||
/* Bitfield to disable some subregions
|
||||
* (1 bit for each 1/8 of region, region must be bigger than 128 bytes) */
|
||||
#define MPU_SUBREGION_DISABLE(value) (MPU_RASR_SRD(value))
|
||||
|
||||
/* --- Access Privilege constants --- */
|
||||
|
||||
/* Access Privilege: no access for all */
|
||||
#define MPU_AP_NOACCESS (MPU_RASR_AP(0))
|
||||
|
||||
/* Access Privilege: no access for unprivileged, readonly for privileged */
|
||||
#define MPU_AP_NOACCESS_PRIV_READONLY (MPU_RASR_AP(5))
|
||||
|
||||
/* Access Privilege: no access for unprivileged, read/write for privileged */
|
||||
#define MPU_AP_NOACCESS_PRIV_READWRITE (MPU_RASR_AP(1))
|
||||
|
||||
/* Access Privilege: readonly for all */
|
||||
#define MPU_AP_READONLY (MPU_RASR_AP(7))
|
||||
|
||||
/* Access Privilege: readonly for unprivileged, read/write for privileged */
|
||||
#define MPU_AP_READONLY_PRIV_READWRITE (MPU_RASR_AP(2))
|
||||
|
||||
/* Access Privilege: read/write for all */
|
||||
#define MPU_AP_READWRITE (MPU_RASR_AP(3))
|
||||
|
||||
/* --- Memory Types Attributes --- */
|
||||
|
||||
/* Strongly-Ordered Shareable */
|
||||
#define MPU_ATTR_STRONGLY_ORDERED (MPU_RASR_TEX(0))
|
||||
|
||||
/* Device Shareable */
|
||||
#define MPU_ATTR_DEVICE (MPU_RASR_TEX(0) | MPU_RASR_B)
|
||||
|
||||
/* Normal, Write-Through Read Allocate */
|
||||
#define MPU_ATTR_NORMAL_WT (MPU_RASR_TEX(0) | MPU_RASR_C)
|
||||
|
||||
/* Normal, Write-Back Read Allocate */
|
||||
#define MPU_ATTR_NORMAL_WB (MPU_RASR_TEX(0) | MPU_RASR_C | MPU_RASR_B)
|
||||
|
||||
/* Normal, Write-Back Read/Write Allocate */
|
||||
#define MPU_ATTR_NORMAL_WB_WA (MPU_RASR_TEX(1) | MPU_RASR_C | MPU_RASR_B)
|
||||
|
||||
/* Normal, Non-cacheable */
|
||||
#define MPU_ATTR_NORMAL (MPU_RASR_TEX(1))
|
||||
|
||||
/* Other Attributes */
|
||||
#define MPU_ATTR_SHAREABLE (MPU_RASR_S)
|
||||
#define MPU_ATTR_EXECUTE_NEVER (MPU_RASR_XN)
|
||||
#define MPU_ATTR_ENABLE (MPU_RASR_ENABLE)
|
||||
|
||||
#endif /* MPU_ARMV7M_H_ */
|
||||
88
arch/arm/mutex.c
Normal file
88
arch/arm/mutex.c
Normal file
@ -0,0 +1,88 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2015, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "barriers.h"
|
||||
#include "chip.h"
|
||||
#include "mutex.h"
|
||||
#include "cpuidle.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MUTEX_LOCKED 1
|
||||
#define MUTEX_UNLOCKED 0
|
||||
|
||||
void mutex_lock(mutex_t* mutex)
|
||||
{
|
||||
while (!mutex_try_lock(mutex)) {
|
||||
cpu_idle();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CONFIG_ARCH_ARMV7A) || defined(CONFIG_ARCH_ARMV7M)
|
||||
|
||||
bool mutex_try_lock(mutex_t* mutex)
|
||||
{
|
||||
uint32_t value;
|
||||
while (true)
|
||||
{
|
||||
// Read the current mutex value and tag the mutex address for exclusive access by the executing processor
|
||||
__asm volatile("ldrex %0, [%1]" : "=r"(value) : "r"(mutex));
|
||||
if (value != MUTEX_UNLOCKED)
|
||||
return false;
|
||||
// Provided the executing processor still has exclusive access to the mutex address, lock it now
|
||||
__asm volatile("strex %0, %1, [%2]" : "=&r"(value) : "r"(MUTEX_LOCKED), "r"(mutex));
|
||||
if (value == 0) /* Check if strex was ok */
|
||||
break;
|
||||
}
|
||||
dmb();
|
||||
return true;
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_ARCH_ARMV5TE)
|
||||
|
||||
bool mutex_try_lock(mutex_t* mutex)
|
||||
{
|
||||
uint32_t value;
|
||||
asm("swp %0, %1, [%2]" : "=&r"(value) : "r"(MUTEX_LOCKED), "r"(mutex));
|
||||
return value == MUTEX_UNLOCKED;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void mutex_unlock(mutex_t* mutex)
|
||||
{
|
||||
dmb();
|
||||
*mutex = MUTEX_UNLOCKED;
|
||||
}
|
||||
|
||||
bool mutex_is_locked(const mutex_t* mutex)
|
||||
{
|
||||
return *mutex != MUTEX_UNLOCKED;
|
||||
}
|
||||
107
arch/arm/swab.h
Normal file
107
arch/arm/swab.h
Normal file
@ -0,0 +1,107 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef ARM_SWAB_H_
|
||||
#define ARM_SWAB_H_
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Public functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(CONFIG_ARCH_ARMV4TE)
|
||||
|
||||
static inline uint16_t swab16(uint16_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
result = ((value & 0xff00) >> 8) |
|
||||
((value & 0x00ff) << 8);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline uint32_t swab32(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
result = ((value & 0x000000ff)<<24) |
|
||||
((value & 0x0000ff00)<<8) |
|
||||
((value & 0x00ff0000)>>8) |
|
||||
((value & 0xff000000)>>24);
|
||||
return result;
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_ARCH_ARMV5TE)
|
||||
|
||||
static inline uint16_t swab16(uint16_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
result = ((value & 0xff00) >> 8) |
|
||||
((value & 0x00ff) << 8);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline uint32_t swab32(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
// ARMv5TE does not support the "rev" instruction
|
||||
asm("eor r3, %1, %1, ror #16\n"
|
||||
"bic r3, r3, #0xff0000\n"
|
||||
"mov %0, %1, ror #8\n"
|
||||
"eor %0, %0, r3, lsr #8" : "=r"(result) : "0"(value) : "r3","cc");
|
||||
return result;
|
||||
}
|
||||
|
||||
#elif defined(CONFIG_ARCH_ARMV7A) ||\
|
||||
defined(CONFIG_ARCH_ARMV7M)
|
||||
|
||||
static inline uint16_t swab16(uint16_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
asm("rev16 %0, %1" : "=r"(result) : "r"(value));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline uint32_t swab32(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
asm("rev %0, %1" : "=r"(result) : "r"(value));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* ARM_SWAB_H_ */
|
||||
39
arch/barriers.h
Normal file
39
arch/barriers.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef BARRIERS_H_
|
||||
#define BARRIERS_H_
|
||||
|
||||
#if defined(CONFIG_ARCH_ARM)
|
||||
#include "arm/barriers.h"
|
||||
#else
|
||||
#error Unsupported architecture!
|
||||
#endif
|
||||
|
||||
#endif /* BARRIERS_H_ */
|
||||
39
arch/cpuidle.h
Normal file
39
arch/cpuidle.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef CPUIDLE_H_
|
||||
#define CPUIDLE_H_
|
||||
|
||||
#if defined(CONFIG_ARCH_ARM)
|
||||
#include "arm/cpuidle.h"
|
||||
#else
|
||||
#error Unsupported architecture!
|
||||
#endif
|
||||
|
||||
#endif /* CPUIDLE_H_ */
|
||||
39
arch/irqflags.h
Normal file
39
arch/irqflags.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef IRQFLAGS_H_
|
||||
#define IRQFLAGS_H_
|
||||
|
||||
#if defined(CONFIG_ARCH_ARM)
|
||||
#include "arm/irqflags.h"
|
||||
#else
|
||||
#error Unsupported architecture!
|
||||
#endif
|
||||
|
||||
#endif /* IRQFLAGS_H_ */
|
||||
138
arch/l1cache.h
Normal file
138
arch/l1cache.h
Normal file
@ -0,0 +1,138 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2015, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef L1CACHE_H_
|
||||
#define L1CACHE_H_
|
||||
|
||||
/*
|
||||
* Functions related to L1 cache maintenance (I-Cache and D-Cache).
|
||||
*
|
||||
* Actual implementation is located in arch/ since L1 is part of the CPU core.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_HAVE_L1CACHE
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Headers
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Invalidate all instruction cache.
|
||||
*/
|
||||
extern void icache_invalidate(void);
|
||||
|
||||
/**
|
||||
* \brief Check if instruction cache is enabled.
|
||||
*/
|
||||
extern bool icache_is_enabled(void);
|
||||
|
||||
/**
|
||||
* \brief Enable instruction cache.
|
||||
*/
|
||||
extern void icache_enable(void);
|
||||
|
||||
/**
|
||||
* \brief Disable instruction cache.
|
||||
*/
|
||||
extern void icache_disable(void);
|
||||
|
||||
/**
|
||||
* \brief Check if data cache is enabled.
|
||||
*/
|
||||
extern bool dcache_is_enabled(void);
|
||||
|
||||
/**
|
||||
* \brief Enable data cache.
|
||||
*/
|
||||
extern void dcache_enable(void);
|
||||
|
||||
/**
|
||||
* \brief Disable the data cache.
|
||||
*/
|
||||
extern void dcache_disable(void);
|
||||
|
||||
/**
|
||||
* \brief Clean the data cache.
|
||||
*/
|
||||
extern void dcache_clean(void);
|
||||
|
||||
/**
|
||||
* \brief Invalidate the data cache.
|
||||
*/
|
||||
extern void dcache_invalidate(void);
|
||||
|
||||
/**
|
||||
* \brief Clean & Invalidate the data cache.
|
||||
*/
|
||||
extern void dcache_clean_invalidate(void);
|
||||
|
||||
/**
|
||||
* \brief Invalidate the data cache within the specified region
|
||||
* \param start virtual start address of region
|
||||
* \param end virtual end address of region
|
||||
*/
|
||||
extern void dcache_invalidate_region(uint32_t start, uint32_t end);
|
||||
|
||||
/**
|
||||
* \brief Clean the data cache within the specified region.
|
||||
* \param start virtual start address of region
|
||||
* \param end virtual end address of region
|
||||
*/
|
||||
extern void dcache_clean_region(uint32_t start, uint32_t end);
|
||||
|
||||
/**
|
||||
* \brief Clean and invalidate the data cache within the specified region.
|
||||
* \param start virtual start address of region
|
||||
* \param end virtual end address of region
|
||||
*/
|
||||
extern void dcache_clean_invalidate_region(uint32_t start, uint32_t end);
|
||||
|
||||
/**
|
||||
* \brief Enable exclusive caching for the L1 cache.
|
||||
*
|
||||
* The L2 cache must also be configured in exclusive mode.
|
||||
*/
|
||||
extern void dcache_set_exclusive(void);
|
||||
|
||||
/**
|
||||
* \brief Allow data to reside in the L1 and L2 caches at the same time.
|
||||
*/
|
||||
extern void dcache_set_non_exclusive(void);
|
||||
|
||||
#endif /* CONFIG_HAVE_L1CACHE */
|
||||
|
||||
#endif /* L1CACHE_H_ */
|
||||
55
arch/mutex.h
Normal file
55
arch/mutex.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2015, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef MUTEX_H_
|
||||
#define MUTEX_H_
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Headers
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Types
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
/* Instances of mutex_t should be word-aligned (ALIGNED(4)) */
|
||||
typedef volatile int mutex_t;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
extern bool mutex_try_lock(mutex_t* mutex);
|
||||
extern void mutex_lock(mutex_t* mutex);
|
||||
extern void mutex_unlock(mutex_t* mutex);
|
||||
extern bool mutex_is_locked(const mutex_t* mutex);
|
||||
|
||||
#endif /* MUTEX_H_ */
|
||||
39
arch/swab.h
Normal file
39
arch/swab.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* SAM Software Package License
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2016, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef SWAB_H_
|
||||
#define SWAB_H_
|
||||
|
||||
#if defined(CONFIG_ARCH_ARM)
|
||||
#include "arm/swab.h"
|
||||
#else
|
||||
#error Unsupported architecture!
|
||||
#endif
|
||||
|
||||
#endif /* SWAB_H_ */
|
||||
35
firmware.c
35
firmware.c
@ -17,11 +17,11 @@ 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 "AT91SAM7S256.h"
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "errors.h"
|
||||
#include "hardware.h"
|
||||
#include "irqflags.h"
|
||||
#include "fat_compat.h"
|
||||
#include "firmware.h"
|
||||
|
||||
@ -156,26 +156,19 @@ RAMFUNC void WriteFirmware(char *name)
|
||||
}
|
||||
size = f_size(&file) - sizeof(UPGRADE);
|
||||
// All interrupts have to be disabled.
|
||||
asm volatile ("mrs r12, CPSR; orr r12, r12, #0xC0; msr CPSR_c, r12"
|
||||
: /* No outputs */
|
||||
: /* No inputs */
|
||||
: "r12", "cc");
|
||||
arch_irq_disable();
|
||||
// asm volatile ("mrs r12, CPSR; orr r12, r12, #0xC0; msr CPSR_c, r12"
|
||||
// : /* No outputs */
|
||||
// : /* No inputs */
|
||||
// : "r12", "cc");
|
||||
|
||||
|
||||
// Hack to foul FatFs to not handle a final partial sector (to avoid a memcpy)
|
||||
file.obj.objsize = (file.obj.objsize + 511) & 0xfffffe00;
|
||||
page = 0;
|
||||
pDst = 0;
|
||||
|
||||
*AT91C_MC_FMR = 48 << 16 | FWS << 8; // MCLK cycles in 1us
|
||||
for (i = 0; i < 16; i++)
|
||||
if (*AT91C_MC_FSR & 1 << 16 + i)
|
||||
{ // page is locked
|
||||
while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready
|
||||
*AT91C_MC_FCR = 0x5A << 24 | i << 6 + 8 | AT91C_MC_FCMD_UNLOCK; // unlock page
|
||||
while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready
|
||||
}
|
||||
|
||||
*AT91C_MC_FMR = 72 << 16 | FWS << 8; // MCLK cycles in 1.5us
|
||||
UnlockFlash();
|
||||
|
||||
while (size)
|
||||
{
|
||||
@ -198,18 +191,18 @@ RAMFUNC void WriteFirmware(char *name)
|
||||
|
||||
// programming time: 13.2 ms per disk sector (512B)
|
||||
pSrc = (unsigned long*)sector_buffer;
|
||||
k = 2;
|
||||
k = 512/FLASH_PAGESIZE;
|
||||
while (k--)
|
||||
{
|
||||
if(size & 2048) DISKLED_ON
|
||||
else DISKLED_OFF;
|
||||
|
||||
#ifndef GCC_OPTIMZES_TOO_MUCH // the latest gcc 4.8.0 calls memcpy for this
|
||||
i = 256 / 4;
|
||||
i = FLASH_PAGESIZE / 4;
|
||||
while (i--)
|
||||
*pDst++ = *pSrc++;
|
||||
#else
|
||||
i = 256 / 8;
|
||||
i = FLASH_PAGESIZE / 8;
|
||||
while (i--) {
|
||||
*pDst++ = *pSrc++;
|
||||
*pDst++ = *pSrc++;
|
||||
@ -217,9 +210,7 @@ RAMFUNC void WriteFirmware(char *name)
|
||||
|
||||
#endif
|
||||
|
||||
while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready
|
||||
*AT91C_MC_FCR = 0x5A << 24 | page << 8 | AT91C_MC_FCMD_START_PROG; // key: 0x5A
|
||||
while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready
|
||||
WriteFlash(page);
|
||||
page++;
|
||||
}
|
||||
|
||||
@ -227,7 +218,7 @@ RAMFUNC void WriteFirmware(char *name)
|
||||
}
|
||||
|
||||
DISKLED_OFF;
|
||||
*AT91C_RSTC_RCR = 0xA5 << 24 | AT91C_RSTC_PERRST | AT91C_RSTC_PROCRST; // restart
|
||||
MCUReset(); // restart
|
||||
for(;;);
|
||||
}
|
||||
#pragma section_no_code_init
|
||||
|
||||
@ -15,9 +15,6 @@ typedef struct
|
||||
unsigned long crc;
|
||||
} UPGRADE;
|
||||
|
||||
#define true -1
|
||||
#define false 0
|
||||
|
||||
unsigned long CalculateCRC32(unsigned long crc, unsigned char *pBuffer, unsigned long nSize);
|
||||
unsigned char CheckFirmware(char *name);
|
||||
void WriteFirmware(char *name) RAMFUNC;
|
||||
|
||||
41
fpga.c
41
fpga.c
@ -22,10 +22,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// 2009-12-10 - changed command header id
|
||||
// 2010-04-14 - changed command header id
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include "AT91SAM7S256.h"
|
||||
#endif
|
||||
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "errors.h"
|
||||
@ -39,6 +35,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "tos.h"
|
||||
#include "mist_cfg.h"
|
||||
|
||||
uint8_t rstval = 0;
|
||||
|
||||
#define CMD_HDRID 0xAACA
|
||||
|
||||
// TODO!
|
||||
@ -238,9 +236,10 @@ static inline void ShiftFpga(unsigned char data)
|
||||
for ( i = 0; i < 8; i++ )
|
||||
{
|
||||
/* Dump to DATA0 and insert a positive edge pulse at the same time */
|
||||
*AT91C_PIOA_CODR = ALTERA_DATA0 | ALTERA_DCLK;
|
||||
if((data >> i) & 1) *AT91C_PIOA_SODR = ALTERA_DATA0;
|
||||
*AT91C_PIOA_SODR = ALTERA_DCLK;
|
||||
FPGA_DATA0_CODR = ALTERA_DATA0;
|
||||
FPGA_CODR = ALTERA_DCLK;
|
||||
if((data >> i) & 1) FPGA_DATA0_SODR = ALTERA_DATA0;
|
||||
FPGA_SODR = ALTERA_DCLK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,9 +252,8 @@ unsigned char ConfigureFpga(char *name)
|
||||
UINT br;
|
||||
|
||||
// set outputs
|
||||
*AT91C_PIOA_SODR = ALTERA_DCLK | ALTERA_DATA0 | ALTERA_NCONFIG;
|
||||
// enable outputs
|
||||
*AT91C_PIOA_OER = ALTERA_DCLK | ALTERA_DATA0 | ALTERA_NCONFIG;
|
||||
FPGA_SODR = ALTERA_DCLK | ALTERA_NCONFIG;
|
||||
FPGA_DATA0_SODR = ALTERA_DATA0;
|
||||
|
||||
if(!name)
|
||||
name = "CORE.RBF";
|
||||
@ -275,14 +273,14 @@ unsigned char ConfigureFpga(char *name)
|
||||
|
||||
/* Drive a transition of 0 to 1 to NCONFIG to indicate start of configuration */
|
||||
for(i=0;i<10;i++)
|
||||
*AT91C_PIOA_CODR = ALTERA_NCONFIG; // must be low for at least 500ns
|
||||
FPGA_CODR = ALTERA_NCONFIG; // must be low for at least 500ns
|
||||
|
||||
*AT91C_PIOA_SODR = ALTERA_NCONFIG;
|
||||
FPGA_SODR = ALTERA_NCONFIG;
|
||||
|
||||
// now wait for NSTATUS to go high
|
||||
// specs: max 800us
|
||||
i = 1000000;
|
||||
while (!(*AT91C_PIOA_PDSR & ALTERA_NSTATUS))
|
||||
while (!(FPGA_PDSR & ALTERA_NSTATUS))
|
||||
{
|
||||
if (--i == 0)
|
||||
{
|
||||
@ -328,7 +326,7 @@ unsigned char ConfigureFpga(char *name)
|
||||
|
||||
/* Check for error through NSTATUS for every 10KB programmed and the last byte */
|
||||
if ( !(i % 10240) || (i == f_size(&file) - 1) ) {
|
||||
if ( !*AT91C_PIOA_PDSR & ALTERA_NSTATUS ) {
|
||||
if ( !FPGA_PDSR & ALTERA_NSTATUS ) {
|
||||
iprintf("FPGA NSTATUS is NOT high!\r");
|
||||
f_close(&file);
|
||||
FatalError(5);
|
||||
@ -343,7 +341,7 @@ unsigned char ConfigureFpga(char *name)
|
||||
DISKLED_OFF;
|
||||
|
||||
// check if DONE is high
|
||||
if (!(*AT91C_PIOA_PDSR & ALTERA_DONE)) {
|
||||
if (!(FPGA_DONE_PDSR & ALTERA_DONE)) {
|
||||
iprintf("FPGA Configuration done but contains error... CONF_DONE is LOW\r");
|
||||
FatalError(5);
|
||||
}
|
||||
@ -361,17 +359,17 @@ unsigned char ConfigureFpga(char *name)
|
||||
|
||||
for ( i = 0; i < 50; i++ )
|
||||
{
|
||||
*AT91C_PIOA_CODR = ALTERA_DCLK;
|
||||
*AT91C_PIOA_SODR = ALTERA_DCLK;
|
||||
FPGA_CODR = ALTERA_DCLK;
|
||||
FPGA_SODR = ALTERA_DCLK;
|
||||
}
|
||||
|
||||
/* Initialization end */
|
||||
|
||||
if ( !(*AT91C_PIOA_PDSR & ALTERA_NSTATUS) ||
|
||||
!(*AT91C_PIOA_PDSR & ALTERA_DONE)) {
|
||||
|
||||
if ( !(FPGA_PDSR & ALTERA_NSTATUS) ||
|
||||
!(FPGA_DONE_PDSR & ALTERA_DONE)) {
|
||||
|
||||
iprintf("FPGA Initialization finish but contains error: NSTATUS is %s and CONF_DONE is %s.\r",
|
||||
((*AT91C_PIOA_PDSR & ALTERA_NSTATUS)?"HIGH":"LOW"), ((*AT91C_PIOA_PDSR & ALTERA_DONE)?"HIGH":"LOW") );
|
||||
((FPGA_PDSR & ALTERA_NSTATUS)?"HIGH":"LOW"), ((FPGA_DONE_PDSR & ALTERA_DONE)?"HIGH":"LOW") );
|
||||
FatalError(5);
|
||||
}
|
||||
|
||||
@ -935,6 +933,7 @@ void fpga_init(char *name) {
|
||||
user_io_detect_core_type();
|
||||
mist_ini_parse();
|
||||
user_io_send_buttons(1);
|
||||
InitDB9();
|
||||
|
||||
if((user_io_core_type() == CORE_TYPE_MINIMIG)||
|
||||
(user_io_core_type() == CORE_TYPE_MINIMIG2)) {
|
||||
|
||||
6
fpga.h
6
fpga.h
@ -15,5 +15,11 @@ void BootExit(void);
|
||||
void ClearMemory(unsigned long base, unsigned long size);
|
||||
unsigned char GetFPGAStatus(void);
|
||||
|
||||
// minimig reset stuff
|
||||
#define SPI_RST_USR 0x1
|
||||
#define SPI_RST_CPU 0x2
|
||||
#define SPI_CPU_HLT 0x4
|
||||
extern uint8_t rstval;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
13
hdd.c
13
hdd.c
@ -25,6 +25,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "swab.h"
|
||||
#include "errors.h"
|
||||
#include "hardware.h"
|
||||
#include "fat_compat.h"
|
||||
@ -36,8 +37,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
#define SWAP(a) ((((a)&0x000000ff)<<24)|(((a)&0x0000ff00)<<8)|(((a)&0x00ff0000)>>8)|(((a)&0xff000000)>>24))
|
||||
|
||||
hardfileTYPE *hardfile[HARDFILES];
|
||||
|
||||
// hardfile structure
|
||||
@ -116,10 +115,10 @@ static void FakeRDB(int unit,int block)
|
||||
strcpy(rdb->rdb_DiskProduct, "repartition!");
|
||||
// swap byte order of strings to be able to "unswap" them after checksum
|
||||
unsigned long *p = (unsigned long*)rdb;
|
||||
for(i=0;i<(8+16)/4;i++) p[40+i] = SWAP(p[40+i]);
|
||||
for(i=0;i<(8+16)/4;i++) p[40+i] = swab32(p[40+i]);
|
||||
RDBChecksum((unsigned long *)rdb);
|
||||
// swap byte order of first 0x40 long values
|
||||
for(i=0;i<0x40;i++) p[i] = SWAP(p[i]);
|
||||
for(i=0;i<0x40;i++) p[i] = swab32(p[i]);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
@ -148,7 +147,7 @@ static void FakeRDB(int unit,int block)
|
||||
RDBChecksum((unsigned long *)pb);
|
||||
// swap byte order of first 0x40 entries
|
||||
unsigned long *p = (unsigned long*)pb;
|
||||
for(i=0;i<0x40;i++) p[i] = SWAP(p[i]);
|
||||
for(i=0;i<0x40;i++) p[i] = swab32(p[i]);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@ -411,10 +410,10 @@ static inline void ATA_ReadSectors(unsigned char* tfr, unsigned short sector, un
|
||||
|
||||
// adjust checksum by the difference between old and new flag value
|
||||
struct RigidDiskBlock *rdb = (struct RigidDiskBlock *)sector_buffer;
|
||||
rdb->rdb_ChkSum = SWAP(SWAP(rdb->rdb_ChkSum) + SWAP(rdb->rdb_Flags) - 0x12);
|
||||
rdb->rdb_ChkSum = swab32(swab32(rdb->rdb_ChkSum) + swab32(rdb->rdb_Flags) - 0x12);
|
||||
|
||||
// adjust flags
|
||||
rdb->rdb_Flags=SWAP(0x12);
|
||||
rdb->rdb_Flags=swab32(0x12);
|
||||
}
|
||||
EnableFpga();
|
||||
spi8(CMD_IDE_DATA_WR); // write data command
|
||||
|
||||
@ -1,323 +1,460 @@
|
||||
/*
|
||||
Copyright 2008, 2009 Jakub Bednarski
|
||||
|
||||
This file is part of Minimig
|
||||
|
||||
Minimig 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.
|
||||
|
||||
Minimig 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 <ctype.h>
|
||||
#include "AT91SAM7S256.h"
|
||||
#include "stdio.h"
|
||||
#include "hardware.h"
|
||||
#include "user_io.h"
|
||||
#include "xmodem.h"
|
||||
#include "ikbd.h"
|
||||
|
||||
uint8_t rstval = 0;
|
||||
|
||||
void __init_hardware(void)
|
||||
{
|
||||
*AT91C_WDTC_WDMR = AT91C_WDTC_WDDIS; // disable watchdog
|
||||
*AT91C_RSTC_RMR = (0xA5 << 24) | AT91C_RSTC_URSTEN; // enable external user reset input
|
||||
*AT91C_MC_FMR = FWS << 8; // Flash wait states
|
||||
|
||||
// configure clock generator
|
||||
*AT91C_CKGR_MOR = AT91C_CKGR_MOSCEN | (40 << 8);
|
||||
while (!(*AT91C_PMC_SR & AT91C_PMC_MOSCS));
|
||||
|
||||
*AT91C_CKGR_PLLR = AT91C_CKGR_OUT_0 | AT91C_CKGR_USBDIV_1 | (25 << 16) | (40 << 8) | 5; // DIV=5 MUL=26 USBDIV=1 (2) PLLCOUNT=40
|
||||
while (!(*AT91C_PMC_SR & AT91C_PMC_LOCK));
|
||||
|
||||
*AT91C_PMC_MCKR = AT91C_PMC_PRES_CLK_2; // master clock register: clock source selection
|
||||
while (!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY));
|
||||
|
||||
*AT91C_PMC_MCKR = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_2; // master clock register: clock source selection
|
||||
while (!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY));
|
||||
|
||||
*AT91C_PIOA_PER = 0xFFFFFFFF; // enable pio on all pins
|
||||
*AT91C_PIOA_SODR = DISKLED; // led off
|
||||
|
||||
#ifdef USB_PUP
|
||||
// disable usb d+/d- pullups if present
|
||||
*AT91C_PIOA_OER = USB_PUP;
|
||||
*AT91C_PIOA_PPUDR = USB_PUP;
|
||||
*AT91C_PIOA_SODR = USB_PUP;
|
||||
#endif
|
||||
|
||||
// enable joystick ports
|
||||
#ifdef JOY0
|
||||
*AT91C_PIOA_PPUER = JOY0;
|
||||
#endif
|
||||
|
||||
#ifdef JOY1
|
||||
*AT91C_PIOA_PPUER = JOY1;
|
||||
#endif
|
||||
|
||||
#ifdef SD_WP
|
||||
// enable SD card signals
|
||||
*AT91C_PIOA_PPUER = SD_WP | SD_CD;
|
||||
#endif
|
||||
|
||||
*AT91C_PIOA_SODR = MMC_SEL | FPGA0 | FPGA1 | FPGA2; // set output data register
|
||||
|
||||
// output enable register
|
||||
*AT91C_PIOA_OER = DISKLED | MMC_SEL | FPGA0 | FPGA1 | FPGA2;
|
||||
// pull-up disable register
|
||||
*AT91C_PIOA_PPUDR = DISKLED | MMC_SEL | FPGA0 | FPGA1 | FPGA2;
|
||||
|
||||
#ifdef XILINX_CCLK
|
||||
// xilinx interface
|
||||
*AT91C_PIOA_SODR = XILINX_CCLK | XILINX_DIN | XILINX_PROG_B;
|
||||
*AT91C_PIOA_OER = XILINX_CCLK | XILINX_DIN | XILINX_PROG_B;
|
||||
*AT91C_PIOA_PPUDR = XILINX_CCLK | XILINX_DIN | XILINX_PROG_B |
|
||||
XILINX_INIT_B | XILINX_DONE;
|
||||
#endif
|
||||
|
||||
#ifdef ALTERA_DCLK
|
||||
// altera interface
|
||||
*AT91C_PIOA_SODR = ALTERA_DCLK | ALTERA_DATA0 | ALTERA_NCONFIG;
|
||||
*AT91C_PIOA_OER = ALTERA_DCLK | ALTERA_DATA0 | ALTERA_NCONFIG;
|
||||
*AT91C_PIOA_PPUDR = ALTERA_DCLK | ALTERA_DATA0 | ALTERA_NCONFIG |
|
||||
ALTERA_NSTATUS | ALTERA_DONE;
|
||||
#endif
|
||||
|
||||
#ifdef MMC_CLKEN
|
||||
// MMC_CLKEN may be present
|
||||
// (but is not used anymore, so it's only setup passive)
|
||||
*AT91C_PIOA_SODR = MMC_CLKEN;
|
||||
*AT91C_PIOA_PPUDR = MMC_CLKEN;
|
||||
#endif
|
||||
|
||||
#ifdef USB_SEL
|
||||
*AT91C_PIOA_SODR = USB_SEL;
|
||||
*AT91C_PIOA_OER = USB_SEL;
|
||||
*AT91C_PIOA_PPUDR = USB_SEL;
|
||||
#endif
|
||||
|
||||
// Enable peripheral clock in the PMC
|
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOA;
|
||||
}
|
||||
|
||||
// A buffer of 256 bytes makes index handling pretty trivial
|
||||
volatile static unsigned char tx_buf[256];
|
||||
volatile static unsigned char tx_rptr, tx_wptr;
|
||||
|
||||
volatile static unsigned char rx_buf[256];
|
||||
volatile static unsigned char rx_rptr, rx_wptr;
|
||||
|
||||
void Usart0IrqHandler(void) {
|
||||
// Read USART status
|
||||
unsigned char status = AT91C_BASE_US0->US_CSR;
|
||||
|
||||
// received something?
|
||||
if(status & AT91C_US_RXRDY) {
|
||||
// read byte from usart
|
||||
unsigned char c = AT91C_BASE_US0->US_RHR;
|
||||
|
||||
// only store byte if rx buffer is not full
|
||||
if((unsigned char)(rx_wptr + 1) != rx_rptr) {
|
||||
// there's space in buffer: use it
|
||||
rx_buf[rx_wptr++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
// ready to transmit further bytes?
|
||||
if(status & AT91C_US_TXRDY) {
|
||||
|
||||
// further bytes to send in buffer?
|
||||
if(tx_wptr != tx_rptr)
|
||||
// yes, simply send it and leave irq enabled
|
||||
AT91C_BASE_US0->US_THR = tx_buf[tx_rptr++];
|
||||
else
|
||||
// nothing else to send, disable interrupt
|
||||
AT91C_BASE_US0->US_IDR = AT91C_US_TXRDY;
|
||||
}
|
||||
}
|
||||
|
||||
// check usart rx buffer for data
|
||||
void USART_Poll(void) {
|
||||
if(user_io_dip_switch1())
|
||||
xmodem_poll();
|
||||
|
||||
while(rx_wptr != rx_rptr) {
|
||||
// this can a little be optimized by sending whole buffer parts
|
||||
// at once and not just single bytes. But that's probably not
|
||||
// worth the effort.
|
||||
char chr = rx_buf[rx_rptr++];
|
||||
|
||||
if(user_io_dip_switch1()) {
|
||||
// if in debug mode use xmodem for file reception
|
||||
xmodem_rx_byte(chr);
|
||||
} else {
|
||||
iprintf("USART RX %d (%c)\n", chr, chr);
|
||||
|
||||
// data available -> send via user_io to core
|
||||
user_io_serial_tx(&chr, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USART_Write(unsigned char c) {
|
||||
#if 0
|
||||
while(!(AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY));
|
||||
AT91C_BASE_US0->US_THR = c;
|
||||
#else
|
||||
if((AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY) && (tx_wptr == tx_rptr)) {
|
||||
// transmitter ready and buffer empty? -> send directly
|
||||
AT91C_BASE_US0->US_THR = c;
|
||||
} else {
|
||||
// transmitter is not ready: block until space in buffer
|
||||
while((unsigned char)(tx_wptr + 1) == tx_rptr);
|
||||
|
||||
// there's space in buffer: use it
|
||||
tx_buf[tx_wptr++] = c;
|
||||
}
|
||||
|
||||
AT91C_BASE_US0->US_IER = AT91C_US_TXRDY; // enable interrupt
|
||||
#endif
|
||||
}
|
||||
|
||||
void USART_Init(unsigned long baudrate) {
|
||||
// Configure PA5 and PA6 for USART0 use
|
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA5_RXD0 | AT91C_PA6_TXD0;
|
||||
|
||||
// Enable the peripheral clock in the PMC
|
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_US0;
|
||||
|
||||
// Reset and disable receiver & transmitter
|
||||
AT91C_BASE_US0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
|
||||
|
||||
// Configure USART0 mode
|
||||
AT91C_BASE_US0->US_MR = AT91C_US_USMODE_NORMAL | AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_8_BITS |
|
||||
AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT | AT91C_US_CHMODE_NORMAL;
|
||||
|
||||
// Configure USART0 rate
|
||||
AT91C_BASE_US0->US_BRGR = MCLK / 16 / baudrate;
|
||||
|
||||
// Enable receiver & transmitter
|
||||
AT91C_BASE_US0->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
|
||||
|
||||
// tx buffer is initially empty
|
||||
tx_rptr = tx_wptr = 0;
|
||||
|
||||
// and so is rx buffer
|
||||
rx_rptr = rx_wptr = 0;
|
||||
|
||||
// Set the USART0 IRQ handler address in AIC Source
|
||||
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_US0] = (unsigned int)Usart0IrqHandler;
|
||||
AT91C_BASE_AIC->AIC_IECR = (1<<AT91C_ID_US0);
|
||||
|
||||
AT91C_BASE_US0->US_IER = AT91C_US_RXRDY; // enable rx interrupt
|
||||
}
|
||||
|
||||
unsigned long CheckButton(void)
|
||||
{
|
||||
#ifdef BUTTON
|
||||
return((~*AT91C_PIOA_PDSR) & BUTTON);
|
||||
#else
|
||||
return user_io_menu_button();
|
||||
#endif
|
||||
}
|
||||
|
||||
void timer0_c_irq_handler(void) {
|
||||
//* Acknowledge interrupt status
|
||||
unsigned int dummy = AT91C_BASE_TC0->TC_SR;
|
||||
|
||||
ikbd_update_time();
|
||||
}
|
||||
|
||||
void Timer_Init(void) {
|
||||
unsigned int dummy;
|
||||
|
||||
//* Open timer0
|
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC0;
|
||||
|
||||
//* Disable the clock and the interrupts
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS ;
|
||||
AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF ;
|
||||
|
||||
//* Clear status bit
|
||||
dummy = AT91C_BASE_TC0->TC_SR;
|
||||
|
||||
//* Set the Mode of the Timer Counter
|
||||
AT91C_BASE_TC0->TC_CMR = 0x04; // :1024
|
||||
|
||||
//* Enable the clock
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN ;
|
||||
|
||||
|
||||
|
||||
//* Open Timer 0 interrupt
|
||||
|
||||
//* Disable the interrupt on the interrupt controller
|
||||
AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_TC0;
|
||||
//* Save the interrupt handler routine pointer and the interrupt priority
|
||||
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned int)timer0_c_irq_handler;
|
||||
//* Store the Source Mode Register
|
||||
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = 1 | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL;
|
||||
//* Clear the interrupt on the interrupt controller
|
||||
AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_TC0;
|
||||
|
||||
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS; // IRQ enable CPC
|
||||
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_TC0;
|
||||
|
||||
//* Start timer0
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG ;
|
||||
|
||||
*AT91C_PITC_PIMR = AT91C_PITC_PITEN | ((MCLK / 16 / 1000 - 1) & AT91C_PITC_PIV); // counting period 1ms
|
||||
}
|
||||
|
||||
// 12 bits accuracy at 1ms = 4096 ms
|
||||
unsigned long GetTimer(unsigned long offset)
|
||||
{
|
||||
unsigned long systimer = (*AT91C_PITC_PIIR & AT91C_PITC_PICNT);
|
||||
systimer += offset << 20;
|
||||
return (systimer); // valid bits [31:20]
|
||||
}
|
||||
|
||||
unsigned long CheckTimer(unsigned long time)
|
||||
{
|
||||
unsigned long systimer = (*AT91C_PITC_PIIR & AT91C_PITC_PICNT);
|
||||
time -= systimer;
|
||||
return(time > (1UL << 31));
|
||||
}
|
||||
|
||||
void WaitTimer(unsigned long time)
|
||||
{
|
||||
time = GetTimer(time);
|
||||
while (!CheckTimer(time));
|
||||
}
|
||||
|
||||
void TIMER_wait(unsigned long ms) {
|
||||
WaitTimer(ms);
|
||||
}
|
||||
|
||||
inline char mmc_inserted() {
|
||||
return !(*AT91C_PIOA_PDSR & SD_CD);
|
||||
}
|
||||
|
||||
char mmc_write_protected() {
|
||||
return (*AT91C_PIOA_PDSR & SD_WP);
|
||||
}
|
||||
|
||||
void MCUReset() {
|
||||
*AT91C_RSTC_RCR = 0xA5 << 24 | AT91C_RSTC_PERRST | AT91C_RSTC_PROCRST | AT91C_RSTC_EXTRST;
|
||||
}
|
||||
|
||||
void InitRTTC() {
|
||||
// reprogram the realtime timer to run at 1Khz
|
||||
AT91C_BASE_RTTC->RTTC_RTMR = 0x8000 / 1000;
|
||||
}
|
||||
|
||||
/*
|
||||
Copyright 2008, 2009 Jakub Bednarski
|
||||
|
||||
This file is part of Minimig
|
||||
|
||||
Minimig 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.
|
||||
|
||||
Minimig 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 <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include "AT91SAM7S256.h"
|
||||
#include "attrs.h"
|
||||
#include "hardware.h"
|
||||
#include "user_io.h"
|
||||
#include "xmodem.h"
|
||||
#include "ikbd.h"
|
||||
#include "usb.h"
|
||||
#include "usbrtc.h"
|
||||
|
||||
void __init_hardware(void)
|
||||
{
|
||||
*AT91C_WDTC_WDMR = AT91C_WDTC_WDDIS; // disable watchdog
|
||||
*AT91C_RSTC_RMR = (0xA5 << 24) | AT91C_RSTC_URSTEN; // enable external user reset input
|
||||
*AT91C_MC_FMR = FWS << 8; // Flash wait states
|
||||
|
||||
// configure clock generator
|
||||
*AT91C_CKGR_MOR = AT91C_CKGR_MOSCEN | (40 << 8);
|
||||
while (!(*AT91C_PMC_SR & AT91C_PMC_MOSCS));
|
||||
|
||||
*AT91C_CKGR_PLLR = AT91C_CKGR_OUT_0 | AT91C_CKGR_USBDIV_1 | (25 << 16) | (40 << 8) | 5; // DIV=5 MUL=26 USBDIV=1 (2) PLLCOUNT=40
|
||||
while (!(*AT91C_PMC_SR & AT91C_PMC_LOCK));
|
||||
|
||||
*AT91C_PMC_MCKR = AT91C_PMC_PRES_CLK_2; // master clock register: clock source selection
|
||||
while (!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY));
|
||||
|
||||
*AT91C_PMC_MCKR = AT91C_PMC_CSS_PLL_CLK | AT91C_PMC_PRES_CLK_2; // master clock register: clock source selection
|
||||
while (!(*AT91C_PMC_SR & AT91C_PMC_MCKRDY));
|
||||
|
||||
*AT91C_PIOA_PER = 0xFFFFFFFF; // enable pio on all pins
|
||||
*AT91C_PIOA_SODR = DISKLED; // led off
|
||||
|
||||
#ifdef USB_PUP
|
||||
// disable usb d+/d- pullups if present
|
||||
*AT91C_PIOA_OER = USB_PUP;
|
||||
*AT91C_PIOA_PPUDR = USB_PUP;
|
||||
*AT91C_PIOA_SODR = USB_PUP;
|
||||
#endif
|
||||
|
||||
// enable joystick ports
|
||||
#ifdef JOY0
|
||||
*AT91C_PIOA_PPUER = JOY0;
|
||||
#endif
|
||||
|
||||
#ifdef JOY1
|
||||
*AT91C_PIOA_PPUER = JOY1;
|
||||
#endif
|
||||
|
||||
#ifdef SD_WP
|
||||
// enable SD card signals
|
||||
*AT91C_PIOA_PPUER = SD_WP | SD_CD;
|
||||
#endif
|
||||
|
||||
*AT91C_PIOA_SODR = MMC_SEL | FPGA0 | FPGA1 | FPGA2; // set output data register
|
||||
|
||||
// output enable register
|
||||
*AT91C_PIOA_OER = DISKLED | MMC_SEL | FPGA0 | FPGA1 | FPGA2;
|
||||
// pull-up disable register
|
||||
*AT91C_PIOA_PPUDR = DISKLED | MMC_SEL | FPGA0 | FPGA1 | FPGA2;
|
||||
|
||||
#ifdef XILINX_CCLK
|
||||
// xilinx interface
|
||||
*AT91C_PIOA_SODR = XILINX_CCLK | XILINX_DIN | XILINX_PROG_B;
|
||||
*AT91C_PIOA_OER = XILINX_CCLK | XILINX_DIN | XILINX_PROG_B;
|
||||
*AT91C_PIOA_PPUDR = XILINX_CCLK | XILINX_DIN | XILINX_PROG_B |
|
||||
XILINX_INIT_B | XILINX_DONE;
|
||||
#endif
|
||||
|
||||
#ifdef ALTERA_DCLK
|
||||
// altera interface
|
||||
*AT91C_PIOA_SODR = ALTERA_DCLK | ALTERA_DATA0 | ALTERA_NCONFIG;
|
||||
*AT91C_PIOA_OER = ALTERA_DCLK | ALTERA_DATA0 | ALTERA_NCONFIG;
|
||||
*AT91C_PIOA_PPUDR = ALTERA_DCLK | ALTERA_DATA0 | ALTERA_NCONFIG |
|
||||
ALTERA_NSTATUS | ALTERA_DONE;
|
||||
#endif
|
||||
|
||||
#ifdef MMC_CLKEN
|
||||
// MMC_CLKEN may be present
|
||||
// (but is not used anymore, so it's only setup passive)
|
||||
*AT91C_PIOA_SODR = MMC_CLKEN;
|
||||
*AT91C_PIOA_PPUDR = MMC_CLKEN;
|
||||
#endif
|
||||
|
||||
#ifdef USB_SEL
|
||||
*AT91C_PIOA_SODR = USB_SEL;
|
||||
*AT91C_PIOA_OER = USB_SEL;
|
||||
*AT91C_PIOA_PPUDR = USB_SEL;
|
||||
#endif
|
||||
|
||||
// Enable peripheral clock in the PMC
|
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOA;
|
||||
}
|
||||
|
||||
// A buffer of 256 bytes makes index handling pretty trivial
|
||||
volatile static unsigned char tx_buf[256];
|
||||
volatile static unsigned char tx_rptr, tx_wptr;
|
||||
|
||||
volatile static unsigned char rx_buf[256];
|
||||
volatile static unsigned char rx_rptr, rx_wptr;
|
||||
|
||||
void Usart0IrqHandler(void) {
|
||||
// Read USART status
|
||||
unsigned char status = AT91C_BASE_US0->US_CSR;
|
||||
|
||||
// received something?
|
||||
if(status & AT91C_US_RXRDY) {
|
||||
// read byte from usart
|
||||
unsigned char c = AT91C_BASE_US0->US_RHR;
|
||||
|
||||
// only store byte if rx buffer is not full
|
||||
if((unsigned char)(rx_wptr + 1) != rx_rptr) {
|
||||
// there's space in buffer: use it
|
||||
rx_buf[rx_wptr++] = c;
|
||||
}
|
||||
}
|
||||
|
||||
// ready to transmit further bytes?
|
||||
if(status & AT91C_US_TXRDY) {
|
||||
|
||||
// further bytes to send in buffer?
|
||||
if(tx_wptr != tx_rptr)
|
||||
// yes, simply send it and leave irq enabled
|
||||
AT91C_BASE_US0->US_THR = tx_buf[tx_rptr++];
|
||||
else
|
||||
// nothing else to send, disable interrupt
|
||||
AT91C_BASE_US0->US_IDR = AT91C_US_TXRDY;
|
||||
}
|
||||
}
|
||||
|
||||
// check usart rx buffer for data
|
||||
void USART_Poll(void) {
|
||||
if(Buttons() & 2)
|
||||
xmodem_poll();
|
||||
|
||||
while(rx_wptr != rx_rptr) {
|
||||
// this can a little be optimized by sending whole buffer parts
|
||||
// at once and not just single bytes. But that's probably not
|
||||
// worth the effort.
|
||||
char chr = rx_buf[rx_rptr++];
|
||||
|
||||
if(Buttons() & 2) {
|
||||
// if in debug mode use xmodem for file reception
|
||||
xmodem_rx_byte(chr);
|
||||
} else {
|
||||
iprintf("USART RX %d (%c)\n", chr, chr);
|
||||
|
||||
// data available -> send via user_io to core
|
||||
user_io_serial_tx(&chr, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USART_Write(unsigned char c) {
|
||||
#if 0
|
||||
while(!(AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY));
|
||||
AT91C_BASE_US0->US_THR = c;
|
||||
#else
|
||||
if((AT91C_BASE_US0->US_CSR & AT91C_US_TXRDY) && (tx_wptr == tx_rptr)) {
|
||||
// transmitter ready and buffer empty? -> send directly
|
||||
AT91C_BASE_US0->US_THR = c;
|
||||
} else {
|
||||
// transmitter is not ready: block until space in buffer
|
||||
while((unsigned char)(tx_wptr + 1) == tx_rptr);
|
||||
|
||||
// there's space in buffer: use it
|
||||
tx_buf[tx_wptr++] = c;
|
||||
}
|
||||
|
||||
AT91C_BASE_US0->US_IER = AT91C_US_TXRDY; // enable interrupt
|
||||
#endif
|
||||
}
|
||||
|
||||
void USART_Init(unsigned long baudrate) {
|
||||
// Configure PA5 and PA6 for USART0 use
|
||||
AT91C_BASE_PIOA->PIO_PDR = AT91C_PA5_RXD0 | AT91C_PA6_TXD0;
|
||||
|
||||
// Enable the peripheral clock in the PMC
|
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_US0;
|
||||
|
||||
// Reset and disable receiver & transmitter
|
||||
AT91C_BASE_US0->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RXDIS | AT91C_US_TXDIS;
|
||||
|
||||
// Configure USART0 mode
|
||||
AT91C_BASE_US0->US_MR = AT91C_US_USMODE_NORMAL | AT91C_US_CLKS_CLOCK | AT91C_US_CHRL_8_BITS |
|
||||
AT91C_US_PAR_NONE | AT91C_US_NBSTOP_1_BIT | AT91C_US_CHMODE_NORMAL;
|
||||
|
||||
// Configure USART0 rate
|
||||
AT91C_BASE_US0->US_BRGR = MCLK / 16 / baudrate;
|
||||
|
||||
// Enable receiver & transmitter
|
||||
AT91C_BASE_US0->US_CR = AT91C_US_RXEN | AT91C_US_TXEN;
|
||||
|
||||
// tx buffer is initially empty
|
||||
tx_rptr = tx_wptr = 0;
|
||||
|
||||
// and so is rx buffer
|
||||
rx_rptr = rx_wptr = 0;
|
||||
|
||||
// Set the USART0 IRQ handler address in AIC Source
|
||||
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_US0] = (unsigned int)Usart0IrqHandler;
|
||||
AT91C_BASE_AIC->AIC_IECR = (1<<AT91C_ID_US0);
|
||||
|
||||
AT91C_BASE_US0->US_IER = AT91C_US_RXRDY; // enable rx interrupt
|
||||
}
|
||||
|
||||
unsigned long CheckButton(void)
|
||||
{
|
||||
#ifdef BUTTON
|
||||
return((~*AT91C_PIOA_PDSR) & BUTTON);
|
||||
#else
|
||||
return MenuButton();
|
||||
#endif
|
||||
}
|
||||
|
||||
void timer0_c_irq_handler(void) {
|
||||
//* Acknowledge interrupt status
|
||||
unsigned int dummy = AT91C_BASE_TC0->TC_SR;
|
||||
|
||||
ikbd_update_time();
|
||||
}
|
||||
|
||||
void Timer_Init(void) {
|
||||
unsigned int dummy;
|
||||
|
||||
//* Open timer0
|
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_TC0;
|
||||
|
||||
//* Disable the clock and the interrupts
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS ;
|
||||
AT91C_BASE_TC0->TC_IDR = 0xFFFFFFFF ;
|
||||
|
||||
//* Clear status bit
|
||||
dummy = AT91C_BASE_TC0->TC_SR;
|
||||
|
||||
//* Set the Mode of the Timer Counter
|
||||
AT91C_BASE_TC0->TC_CMR = 0x04; // :1024
|
||||
|
||||
//* Enable the clock
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN ;
|
||||
|
||||
|
||||
|
||||
//* Open Timer 0 interrupt
|
||||
|
||||
//* Disable the interrupt on the interrupt controller
|
||||
AT91C_BASE_AIC->AIC_IDCR = 1 << AT91C_ID_TC0;
|
||||
//* Save the interrupt handler routine pointer and the interrupt priority
|
||||
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_TC0] = (unsigned int)timer0_c_irq_handler;
|
||||
//* Store the Source Mode Register
|
||||
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_TC0] = 1 | AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL;
|
||||
//* Clear the interrupt on the interrupt controller
|
||||
AT91C_BASE_AIC->AIC_ICCR = 1 << AT91C_ID_TC0;
|
||||
|
||||
AT91C_BASE_TC0->TC_IER = AT91C_TC_CPCS; // IRQ enable CPC
|
||||
AT91C_BASE_AIC->AIC_IECR = 1 << AT91C_ID_TC0;
|
||||
|
||||
//* Start timer0
|
||||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_SWTRG ;
|
||||
|
||||
*AT91C_PITC_PIMR = AT91C_PITC_PITEN | ((MCLK / 16 / 1000 - 1) & AT91C_PITC_PIV); // counting period 1ms
|
||||
}
|
||||
|
||||
// 12 bits accuracy at 1ms = 4096 ms
|
||||
unsigned long GetTimer(unsigned long offset)
|
||||
{
|
||||
unsigned long systimer = (*AT91C_PITC_PIIR & AT91C_PITC_PICNT);
|
||||
systimer += offset << 20;
|
||||
return (systimer); // valid bits [31:20]
|
||||
}
|
||||
|
||||
unsigned long CheckTimer(unsigned long time)
|
||||
{
|
||||
unsigned long systimer = (*AT91C_PITC_PIIR & AT91C_PITC_PICNT);
|
||||
time -= systimer;
|
||||
return(time > (1UL << 31));
|
||||
}
|
||||
|
||||
void WaitTimer(unsigned long time)
|
||||
{
|
||||
time = GetTimer(time);
|
||||
while (!CheckTimer(time));
|
||||
}
|
||||
|
||||
void TIMER_wait(unsigned long ms) {
|
||||
WaitTimer(ms);
|
||||
}
|
||||
|
||||
inline char mmc_inserted() {
|
||||
return !(*AT91C_PIOA_PDSR & SD_CD);
|
||||
}
|
||||
|
||||
char mmc_write_protected() {
|
||||
return (*AT91C_PIOA_PDSR & SD_WP);
|
||||
}
|
||||
|
||||
void InitRTTC() {
|
||||
// reprogram the realtime timer to run at 1Khz
|
||||
AT91C_BASE_RTTC->RTTC_RTMR = 0x8000 / 1000;
|
||||
}
|
||||
|
||||
int GetSPICLK() {
|
||||
return (MCLK / ((AT91C_SPI_CSR[0] & AT91C_SPI_SCBR) >> 8) / 1000000);
|
||||
}
|
||||
|
||||
// permanent state of adc inputs used for dip switches
|
||||
static unsigned char adc_state = 0;
|
||||
AT91PS_ADC a_pADC = AT91C_BASE_ADC;
|
||||
AT91PS_PMC a_pPMC = AT91C_BASE_PMC;
|
||||
|
||||
static void PollOneADC() {
|
||||
static unsigned char adc_cnt = 0xff;
|
||||
|
||||
// fetch result from previous run
|
||||
if(adc_cnt != 0xff) {
|
||||
unsigned int result;
|
||||
|
||||
// wait for end of convertion
|
||||
while(!(AT91C_BASE_ADC->ADC_SR & (1 << (4+adc_cnt))));
|
||||
switch (adc_cnt) {
|
||||
case 0: result = AT91C_BASE_ADC->ADC_CDR4; break;
|
||||
case 1: result = AT91C_BASE_ADC->ADC_CDR5; break;
|
||||
case 2: result = AT91C_BASE_ADC->ADC_CDR6; break;
|
||||
case 3: result = AT91C_BASE_ADC->ADC_CDR7; break;
|
||||
}
|
||||
|
||||
if(result < 128) adc_state |= (1<<adc_cnt);
|
||||
if(result > 128) adc_state &= ~(1<<adc_cnt);
|
||||
}
|
||||
|
||||
adc_cnt = (adc_cnt + 1)&3;
|
||||
|
||||
// Enable desired chanel
|
||||
AT91C_BASE_ADC->ADC_CHER = 1 << (4+adc_cnt);
|
||||
|
||||
// Start conversion
|
||||
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
|
||||
}
|
||||
|
||||
void InitADC(void) {
|
||||
// Enable clock for interface
|
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_ADC;
|
||||
|
||||
// Reset
|
||||
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
|
||||
AT91C_BASE_ADC->ADC_CR = 0x0;
|
||||
|
||||
// Set maximum startup time and hold time
|
||||
AT91C_BASE_ADC->ADC_MR = 0x0F1F0F00 | AT91C_ADC_LOWRES_8_BIT;
|
||||
|
||||
// make sure we get the first values immediately
|
||||
PollOneADC();
|
||||
PollOneADC();
|
||||
PollOneADC();
|
||||
PollOneADC();
|
||||
}
|
||||
|
||||
// poll one adc channel every 25ms
|
||||
void PollADC() {
|
||||
static long adc_timer = 0;
|
||||
|
||||
if(CheckTimer(adc_timer)) {
|
||||
adc_timer = GetTimer(25);
|
||||
PollOneADC();
|
||||
}
|
||||
}
|
||||
|
||||
// user, menu, DIP1, DIP2
|
||||
unsigned char Buttons() {
|
||||
return (adc_state);
|
||||
}
|
||||
|
||||
unsigned char MenuButton() {
|
||||
return (adc_state & 4);
|
||||
}
|
||||
|
||||
unsigned char UserButton() {
|
||||
return (adc_state & 8);
|
||||
}
|
||||
|
||||
void InitDB9() {}
|
||||
|
||||
// poll db9 joysticks
|
||||
char GetDB9(char index, unsigned char *joy_map) {
|
||||
static int joy0_state = JOY0;
|
||||
static int joy1_state = JOY1;
|
||||
if (!index) {
|
||||
if((*AT91C_PIOA_PDSR & JOY0) != joy0_state) {
|
||||
joy0_state = *AT91C_PIOA_PDSR & JOY0;
|
||||
*joy_map = 0;
|
||||
if(!(joy0_state & JOY0_UP)) *joy_map |= JOY_UP;
|
||||
if(!(joy0_state & JOY0_DOWN)) *joy_map |= JOY_DOWN;
|
||||
if(!(joy0_state & JOY0_LEFT)) *joy_map |= JOY_LEFT;
|
||||
if(!(joy0_state & JOY0_RIGHT)) *joy_map |= JOY_RIGHT;
|
||||
if(!(joy0_state & JOY0_BTN1)) *joy_map |= JOY_BTN1;
|
||||
if(!(joy0_state & JOY0_BTN2)) *joy_map |= JOY_BTN2;
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
} else {
|
||||
if((*AT91C_PIOA_PDSR & JOY1) != joy1_state) {
|
||||
joy1_state = *AT91C_PIOA_PDSR & JOY1;
|
||||
*joy_map = 0;
|
||||
if(!(joy1_state & JOY1_UP)) *joy_map |= JOY_UP;
|
||||
if(!(joy1_state & JOY1_DOWN)) *joy_map |= JOY_DOWN;
|
||||
if(!(joy1_state & JOY1_LEFT)) *joy_map |= JOY_LEFT;
|
||||
if(!(joy1_state & JOY1_RIGHT)) *joy_map |= JOY_RIGHT;
|
||||
if(!(joy1_state & JOY1_BTN1)) *joy_map |= JOY_BTN1;
|
||||
if(!(joy1_state & JOY1_BTN2)) *joy_map |= JOY_BTN2;
|
||||
return 1;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
char GetRTC(unsigned char *d) {
|
||||
return usb_rtc_get_time(d);
|
||||
}
|
||||
|
||||
char SetRTC(unsigned char *d) {
|
||||
return usb_rtc_set_time(d);
|
||||
}
|
||||
|
||||
void RAMFUNC UnlockFlash() {
|
||||
*AT91C_MC_FMR = 48 << 16 | FWS << 8; // MCLK cycles in 1us
|
||||
for (int i = 0; i < 16; i++)
|
||||
if (*AT91C_MC_FSR & 1 << 16 + i)
|
||||
{ // page is locked
|
||||
while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready
|
||||
*AT91C_MC_FCR = 0x5A << 24 | i << 6 + 8 | AT91C_MC_FCMD_UNLOCK; // unlock page
|
||||
while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready
|
||||
}
|
||||
|
||||
*AT91C_MC_FMR = 72 << 16 | FWS << 8; // MCLK cycles in 1.5us
|
||||
}
|
||||
|
||||
void RAMFUNC WriteFlash(int page) {
|
||||
while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready
|
||||
*AT91C_MC_FCR = 0x5A << 24 | page << 8 | AT91C_MC_FCMD_START_PROG; // key: 0x5A
|
||||
while (!(*AT91C_MC_FSR & AT91C_MC_FRDY)); // wait for ready
|
||||
}
|
||||
@ -1,102 +1,138 @@
|
||||
#include "AT91SAM7S256.h"
|
||||
|
||||
#ifndef HARDWARE_H
|
||||
#define HARDWARE_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define MCLK 48000000
|
||||
#define FWS 1 // Flash wait states
|
||||
|
||||
#define DISKLED AT91C_PIO_PA29
|
||||
#define DISKLED_ON *AT91C_PIOA_CODR = DISKLED;
|
||||
#define DISKLED_OFF *AT91C_PIOA_SODR = DISKLED;
|
||||
#define MMC_SEL AT91C_PIO_PA31
|
||||
#define USB_SEL AT91C_PIO_PA11
|
||||
#define USB_PUP AT91C_PIO_PA16
|
||||
#define SD_WP AT91C_PIO_PA1
|
||||
#define SD_CD AT91C_PIO_PA0
|
||||
|
||||
#ifdef EMIST
|
||||
// xilinx programming interface
|
||||
#define XILINX_DONE AT91C_PIO_PA4
|
||||
#define XILINX_DIN AT91C_PIO_PA9
|
||||
#define XILINX_INIT_B AT91C_PIO_PA8
|
||||
#define XILINX_PROG_B AT91C_PIO_PA7
|
||||
#define XILINX_CCLK AT91C_PIO_PA15
|
||||
#else
|
||||
// altera programming interface
|
||||
#define ALTERA_DONE AT91C_PIO_PA4
|
||||
#define ALTERA_DATA0 AT91C_PIO_PA9
|
||||
#define ALTERA_NCONFIG AT91C_PIO_PA8
|
||||
#define ALTERA_NSTATUS AT91C_PIO_PA7
|
||||
#define ALTERA_DCLK AT91C_PIO_PA15
|
||||
#endif
|
||||
|
||||
// db9 joystick ports
|
||||
#define JOY1_UP AT91C_PIO_PA28
|
||||
#define JOY1_DOWN AT91C_PIO_PA27
|
||||
#define JOY1_LEFT AT91C_PIO_PA26
|
||||
#define JOY1_RIGHT AT91C_PIO_PA25
|
||||
#define JOY1_BTN1 AT91C_PIO_PA24
|
||||
#define JOY1_BTN2 AT91C_PIO_PA23
|
||||
#define JOY1 (JOY1_UP|JOY1_DOWN|JOY1_LEFT|JOY1_RIGHT|JOY1_BTN1|JOY1_BTN2)
|
||||
|
||||
#define JOY0_UP AT91C_PIO_PA22
|
||||
#define JOY0_DOWN AT91C_PIO_PA21
|
||||
#define JOY0_LEFT AT91C_PIO_PA20
|
||||
#define JOY0_RIGHT AT91C_PIO_PA19
|
||||
#define JOY0_BTN1 AT91C_PIO_PA18
|
||||
#define JOY0_BTN2 AT91C_PIO_PA17
|
||||
#define JOY0 (JOY0_UP|JOY0_DOWN|JOY0_LEFT|JOY0_RIGHT|JOY0_BTN1|JOY0_BTN2)
|
||||
|
||||
// chip selects for FPGA communication
|
||||
#define FPGA0 AT91C_PIO_PA10
|
||||
#define FPGA1 AT91C_PIO_PA3
|
||||
#define FPGA2 AT91C_PIO_PA2
|
||||
|
||||
#define FPGA3 AT91C_PIO_PA9 // same as ALTERA_DATA0
|
||||
|
||||
#define VBL AT91C_PIO_PA7
|
||||
|
||||
char mmc_inserted(void);
|
||||
void USART_Init(unsigned long baudrate);
|
||||
void USART_Write(unsigned char c);
|
||||
unsigned char USART_Read(void);
|
||||
|
||||
unsigned long CheckButton(void);
|
||||
void Timer_Init(void);
|
||||
unsigned long GetTimer(unsigned long offset);
|
||||
unsigned long CheckTimer(unsigned long t);
|
||||
void WaitTimer(unsigned long time);
|
||||
|
||||
void TIMER_wait(unsigned long ms);
|
||||
|
||||
void USART_Poll(void);
|
||||
|
||||
void MCUReset();
|
||||
|
||||
void InitRTTC();
|
||||
|
||||
int inline GetRTTC() {return (int)(AT91C_BASE_RTTC->RTTC_RTVR);}
|
||||
|
||||
#ifdef FPGA3
|
||||
// the MiST has the user inout on the arm controller
|
||||
void EnableIO(void);
|
||||
void DisableIO(void);
|
||||
#endif
|
||||
|
||||
#define DEBUG_FUNC_IN()
|
||||
#define DEBUG_FUNC_OUT()
|
||||
|
||||
#ifdef __GNUC__
|
||||
void __init_hardware(void);
|
||||
#endif
|
||||
|
||||
// minimig reset stuff
|
||||
#define SPI_RST_USR 0x1
|
||||
#define SPI_RST_CPU 0x2
|
||||
#define SPI_CPU_HLT 0x4
|
||||
extern uint8_t rstval;
|
||||
|
||||
#endif // HARDWARE_H
|
||||
#include "AT91SAM7S256.h"
|
||||
|
||||
#ifndef HARDWARE_H
|
||||
#define HARDWARE_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define MCLK 48000000
|
||||
#define FWS 1 // Flash wait states
|
||||
#define FLASH_PAGESIZE 256
|
||||
|
||||
#define DISKLED AT91C_PIO_PA29
|
||||
#define DISKLED_ON *AT91C_PIOA_CODR = DISKLED;
|
||||
#define DISKLED_OFF *AT91C_PIOA_SODR = DISKLED;
|
||||
#define MMC_SEL AT91C_PIO_PA31
|
||||
#define USB_SEL AT91C_PIO_PA11
|
||||
#define USB_PUP AT91C_PIO_PA16
|
||||
#define SD_WP AT91C_PIO_PA1
|
||||
#define SD_CD AT91C_PIO_PA0
|
||||
|
||||
|
||||
// fpga programming interface
|
||||
#define FPGA_OER *AT91C_PIOA_OER
|
||||
#define FPGA_SODR *AT91C_PIOA_SODR
|
||||
#define FPGA_CODR *AT91C_PIOA_CODR
|
||||
#define FPGA_PDSR *AT91C_PIOA_PDSR
|
||||
#define FPGA_DONE_PDSR FPGA_PDSR
|
||||
#define FPGA_DATA0_CODR FPGA_CODR
|
||||
#define FPGA_DATA0_SODR FPGA_SODR
|
||||
|
||||
#ifdef EMIST
|
||||
// xilinx programming interface
|
||||
#define XILINX_DONE AT91C_PIO_PA4
|
||||
#define XILINX_DIN AT91C_PIO_PA9
|
||||
#define XILINX_INIT_B AT91C_PIO_PA8
|
||||
#define XILINX_PROG_B AT91C_PIO_PA7
|
||||
#define XILINX_CCLK AT91C_PIO_PA15
|
||||
#else
|
||||
// altera programming interface
|
||||
#define ALTERA_DONE AT91C_PIO_PA4
|
||||
#define ALTERA_DATA0 AT91C_PIO_PA9
|
||||
#define ALTERA_NCONFIG AT91C_PIO_PA8
|
||||
#define ALTERA_NSTATUS AT91C_PIO_PA7
|
||||
#define ALTERA_DCLK AT91C_PIO_PA15
|
||||
#endif
|
||||
|
||||
// db9 joystick ports
|
||||
#define JOY1_UP AT91C_PIO_PA28
|
||||
#define JOY1_DOWN AT91C_PIO_PA27
|
||||
#define JOY1_LEFT AT91C_PIO_PA26
|
||||
#define JOY1_RIGHT AT91C_PIO_PA25
|
||||
#define JOY1_BTN1 AT91C_PIO_PA24
|
||||
#define JOY1_BTN2 AT91C_PIO_PA23
|
||||
#define JOY1 (JOY1_UP|JOY1_DOWN|JOY1_LEFT|JOY1_RIGHT|JOY1_BTN1|JOY1_BTN2)
|
||||
|
||||
#define JOY0_UP AT91C_PIO_PA22
|
||||
#define JOY0_DOWN AT91C_PIO_PA21
|
||||
#define JOY0_LEFT AT91C_PIO_PA20
|
||||
#define JOY0_RIGHT AT91C_PIO_PA19
|
||||
#define JOY0_BTN1 AT91C_PIO_PA18
|
||||
#define JOY0_BTN2 AT91C_PIO_PA17
|
||||
#define JOY0 (JOY0_UP|JOY0_DOWN|JOY0_LEFT|JOY0_RIGHT|JOY0_BTN1|JOY0_BTN2)
|
||||
|
||||
// chip selects for FPGA communication
|
||||
#define FPGA0 AT91C_PIO_PA10
|
||||
#define FPGA1 AT91C_PIO_PA3
|
||||
#define FPGA2 AT91C_PIO_PA2
|
||||
|
||||
#define FPGA3 AT91C_PIO_PA9 // same as ALTERA_DATA0
|
||||
|
||||
#define VBL AT91C_PIO_PA7
|
||||
|
||||
#define USB_LOAD_VAR *(int*)(0x0020FF04)
|
||||
#define USB_LOAD_VALUE 12345678
|
||||
|
||||
#define DEBUG_MODE_VAR *(int*)(0x0020FF08)
|
||||
#define DEBUG_MODE_VALUE 87654321
|
||||
#define DEBUG_MODE (DEBUG_MODE_VAR == DEBUG_MODE_VALUE)
|
||||
|
||||
#define VIDEO_KEEP_VALUE 0x87654321
|
||||
#define VIDEO_KEEP_VAR (*(int*)0x0020FF10)
|
||||
#define VIDEO_ALTERED_VAR (*(uint8_t*)0x0020FF14)
|
||||
#define VIDEO_SD_DISABLE_VAR (*(uint8_t*)0x0020FF15)
|
||||
#define VIDEO_YPBPR_VAR (*(uint8_t*)0x0020FF16)
|
||||
|
||||
char mmc_inserted(void);
|
||||
void USART_Init(unsigned long baudrate);
|
||||
void USART_Write(unsigned char c);
|
||||
unsigned char USART_Read(void);
|
||||
|
||||
unsigned long CheckButton(void);
|
||||
void Timer_Init(void);
|
||||
unsigned long GetTimer(unsigned long offset);
|
||||
unsigned long CheckTimer(unsigned long t);
|
||||
void WaitTimer(unsigned long time);
|
||||
|
||||
void TIMER_wait(unsigned long ms);
|
||||
|
||||
void USART_Poll(void);
|
||||
|
||||
void inline MCUReset() {*AT91C_RSTC_RCR = 0xA5 << 24 | AT91C_RSTC_PERRST | AT91C_RSTC_PROCRST | AT91C_RSTC_EXTRST;}
|
||||
|
||||
void InitRTTC();
|
||||
|
||||
int inline GetRTTC() {return (int)(AT91C_BASE_RTTC->RTTC_RTVR);}
|
||||
|
||||
int GetSPICLK();
|
||||
|
||||
void InitADC(void);
|
||||
void PollADC();
|
||||
// user, menu, DIP2, DIP1
|
||||
unsigned char Buttons();
|
||||
unsigned char MenuButton();
|
||||
unsigned char UserButton();
|
||||
|
||||
void InitDB9();
|
||||
char GetDB9(char index, unsigned char *joy_map);
|
||||
|
||||
char GetRTC(unsigned char *d);
|
||||
char SetRTC(unsigned char *d);
|
||||
|
||||
void UnlockFlash();
|
||||
void WriteFlash(int page);
|
||||
|
||||
#ifdef FPGA3
|
||||
// the MiST has the user inout on the arm controller
|
||||
void EnableIO(void);
|
||||
void DisableIO(void);
|
||||
#endif
|
||||
|
||||
#define DEBUG_FUNC_IN()
|
||||
#define DEBUG_FUNC_OUT()
|
||||
|
||||
#ifdef __GNUC__
|
||||
void __init_hardware(void);
|
||||
#endif
|
||||
|
||||
#endif // HARDWARE_H
|
||||
@ -38,7 +38,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#include "spi.h"
|
||||
|
||||
#include "mmc.h"
|
||||
#include "fat_compat.h"
|
||||
|
||||
// variables
|
||||
static unsigned char crc;
|
||||
@ -1,5 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include "idxfile.h"
|
||||
#include "hardware.h"
|
||||
|
||||
IDXFile sd_image[SD_IMAGES];
|
||||
|
||||
|
||||
6
ikbd.c
6
ikbd.c
@ -31,7 +31,7 @@
|
||||
#include "spi.h"
|
||||
#include "ikbd.h"
|
||||
#include "debug.h"
|
||||
#include "usb.h"
|
||||
#include "hardware.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define IKBD_AUTO_MS 20
|
||||
@ -272,7 +272,7 @@ void ikbd_handler_time_set(void) {
|
||||
DisableIO();
|
||||
|
||||
// try to set time on rtc if present
|
||||
usb_rtc_set_time(ikbd.date);
|
||||
SetRTC(ikbd.date);
|
||||
|
||||
spi_uio_cmd_cont(UIO_IKBD_IN);
|
||||
|
||||
@ -289,7 +289,7 @@ void ikbd_handler_interrogate_time(void) {
|
||||
DisableIO();
|
||||
|
||||
// try to fetch time from rtc if present
|
||||
usb_rtc_get_time(ikbd.date);
|
||||
GetRTC(ikbd.date);
|
||||
|
||||
spi_uio_cmd_cont(UIO_IKBD_IN);
|
||||
|
||||
|
||||
4
main.c
4
main.c
@ -107,7 +107,6 @@ extern void inserttestfloppy();
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint8_t tmp;
|
||||
uint8_t mmc_ok = 0;
|
||||
|
||||
#ifdef __GNUC__
|
||||
@ -135,8 +134,7 @@ int main(void)
|
||||
|
||||
// TODO: If MMC fails try to wait for USB storage
|
||||
|
||||
tmp = MCLK / ((AT91C_SPI_CSR[0] & AT91C_SPI_SCBR) >> 8) / 1000000;
|
||||
iprintf("spiclk: %u MHz\r", tmp);
|
||||
iprintf("spiclk: %u MHz\r", GetSPICLK());
|
||||
|
||||
usb_init();
|
||||
|
||||
|
||||
6
tos.c
6
tos.c
@ -326,6 +326,7 @@ static void handle_acsi(unsigned char *buffer) {
|
||||
|
||||
if(lba+length <= blocks) {
|
||||
DISKLED_ON;
|
||||
#ifndef SD_NO_DIRECT_MODE
|
||||
if (user_io_core_type() == CORE_TYPE_MIST2) {
|
||||
// SD-Card -> FPGA direct SPI transfer on MIST2
|
||||
if(hdd_direct && target == 0) {
|
||||
@ -337,6 +338,7 @@ static void handle_acsi(unsigned char *buffer) {
|
||||
FileReadBlockEx(&sd_image[target+2].file, 0, length);
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
while(length) {
|
||||
if(hdd_direct && target == 0) {
|
||||
if(user_io_dip_switch1())
|
||||
@ -351,7 +353,9 @@ static void handle_acsi(unsigned char *buffer) {
|
||||
mist_memory_write_block(sector_buffer);
|
||||
length--;
|
||||
}
|
||||
#ifndef SD_NO_DIRECT_MODE
|
||||
}
|
||||
#endif
|
||||
DISKLED_OFF;
|
||||
dma_ack(0x00);
|
||||
asc[target] = 0x00;
|
||||
@ -1071,7 +1075,7 @@ void tos_poll() {
|
||||
mist_get_dmastate();
|
||||
|
||||
// check the user button
|
||||
if(user_io_user_button()) {
|
||||
if(!MenuButton() && UserButton()) {
|
||||
if(timer == 1)
|
||||
timer = GetTimer(1000);
|
||||
else if(timer != 2)
|
||||
|
||||
@ -8,9 +8,9 @@
|
||||
#include "hidparser.h"
|
||||
#include "debug.h"
|
||||
#include "joymapping.h"
|
||||
#include "hardware.h"
|
||||
#include "../utils.h"
|
||||
#include "../user_io.h"
|
||||
#include "../hardware.h"
|
||||
#include "../mist_cfg.h"
|
||||
#include "../osd.h"
|
||||
#include "../state.h"
|
||||
|
||||
151
user_io.c
151
user_io.c
@ -1,4 +1,3 @@
|
||||
#include "AT91SAM7S256.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -57,11 +56,6 @@ extern char rom_direct_upload;
|
||||
// core variant (mostly for arcades)
|
||||
static char core_mod = 0;
|
||||
|
||||
// permanent state of adc inputs used for dip switches
|
||||
static unsigned char adc_state = 0;
|
||||
AT91PS_ADC a_pADC = AT91C_BASE_ADC;
|
||||
AT91PS_PMC a_pPMC = AT91C_BASE_PMC;
|
||||
|
||||
// keep state of caps lock
|
||||
static char caps_lock_toggle = 0;
|
||||
|
||||
@ -87,12 +81,6 @@ bool scrl_status = 0;
|
||||
#define RTC_FREQ 1000 // 1 s
|
||||
static unsigned long rtc_timer;
|
||||
|
||||
#define VIDEO_KEEP_VALUE 0x87654321
|
||||
#define video_keep (*(int*)0x0020FF10)
|
||||
#define video_altered (*(uint8_t*)0x0020FF14)
|
||||
#define video_sd_disable (*(uint8_t*)0x0020FF15)
|
||||
#define video_ypbpr (*(uint8_t*)0x0020FF16)
|
||||
|
||||
static unsigned char modifier = 0, pressed[6] = { 0,0,0,0,0,0 };
|
||||
|
||||
static unsigned char ps2_typematic_rate = 0x80;
|
||||
@ -117,64 +105,6 @@ char user_io_osd_is_visible() {
|
||||
return osd_is_visible;
|
||||
}
|
||||
|
||||
static void PollOneAdc() {
|
||||
static unsigned char adc_cnt = 0xff;
|
||||
|
||||
// fetch result from previous run
|
||||
if(adc_cnt != 0xff) {
|
||||
unsigned int result;
|
||||
|
||||
// wait for end of convertion
|
||||
while(!(AT91C_BASE_ADC->ADC_SR & (1 << (4+adc_cnt))));
|
||||
|
||||
switch (adc_cnt) {
|
||||
case 0: result = AT91C_BASE_ADC->ADC_CDR4; break;
|
||||
case 1: result = AT91C_BASE_ADC->ADC_CDR5; break;
|
||||
case 2: result = AT91C_BASE_ADC->ADC_CDR6; break;
|
||||
case 3: result = AT91C_BASE_ADC->ADC_CDR7; break;
|
||||
}
|
||||
|
||||
if(result < 128) adc_state |= (1<<adc_cnt);
|
||||
if(result > 128) adc_state &= ~(1<<adc_cnt);
|
||||
}
|
||||
|
||||
adc_cnt = (adc_cnt + 1)&3;
|
||||
|
||||
// Enable desired chanel
|
||||
AT91C_BASE_ADC->ADC_CHER = 1 << (4+adc_cnt);
|
||||
|
||||
// Start conversion
|
||||
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
|
||||
}
|
||||
|
||||
static void InitADC(void) {
|
||||
// Enable clock for interface
|
||||
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_ADC;
|
||||
|
||||
// Reset
|
||||
AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
|
||||
AT91C_BASE_ADC->ADC_CR = 0x0;
|
||||
|
||||
// Set maximum startup time and hold time
|
||||
AT91C_BASE_ADC->ADC_MR = 0x0F1F0F00 | AT91C_ADC_LOWRES_8_BIT;
|
||||
|
||||
// make sure we get the first values immediately
|
||||
PollOneAdc();
|
||||
PollOneAdc();
|
||||
PollOneAdc();
|
||||
PollOneAdc();
|
||||
}
|
||||
|
||||
// poll one adc channel every 25ms
|
||||
static void PollAdc() {
|
||||
static long adc_timer = 0;
|
||||
|
||||
if(CheckTimer(adc_timer)) {
|
||||
adc_timer = GetTimer(25);
|
||||
PollOneAdc();
|
||||
}
|
||||
}
|
||||
|
||||
void user_io_reset() {
|
||||
// no sd card image selected, SD card accesses will go directly
|
||||
// to the card (first slot, and only until the first unmount)
|
||||
@ -198,15 +128,15 @@ void user_io_init() {
|
||||
|
||||
user_io_reset();
|
||||
|
||||
if(video_keep != VIDEO_KEEP_VALUE) video_altered = 0;
|
||||
video_keep = 0;
|
||||
if(VIDEO_KEEP_VAR != VIDEO_KEEP_VALUE) VIDEO_ALTERED_VAR = 0;
|
||||
VIDEO_KEEP_VAR = 0;
|
||||
|
||||
// mark remap table as unused
|
||||
memset(key_remap_table, 0, sizeof(key_remap_table));
|
||||
|
||||
InitADC();
|
||||
|
||||
if(user_io_menu_button()) DEBUG_MODE_VAR = DEBUG_MODE ? 0 : DEBUG_MODE_VALUE;
|
||||
if(MenuButton()) DEBUG_MODE_VAR = DEBUG_MODE ? 0 : DEBUG_MODE_VALUE;
|
||||
iprintf("debug_mode = %d\n", DEBUG_MODE);
|
||||
|
||||
ikbd_init();
|
||||
@ -275,7 +205,7 @@ void user_io_send_rtc(void) {
|
||||
uint8_t date[7]; //year,month,date,hour,min,sec,day
|
||||
uint8_t i;
|
||||
|
||||
if (usb_rtc_get_time((uint8_t*)&date)) {
|
||||
if (GetRTC((uint8_t*)&date)) {
|
||||
//iprintf("Sending time of day %u:%02u:%02u %u.%u.%u\n",
|
||||
// date[3], date[4], date[5], date[2], date[1], 1900 + date[0]);
|
||||
spi_uio_cmd_cont(UIO_SET_RTC);
|
||||
@ -297,7 +227,11 @@ void user_io_detect_core_type() {
|
||||
EnableIO();
|
||||
core_type = SPI(0xff);
|
||||
DisableIO();
|
||||
#ifdef SD_NO_DIRECT_MODE
|
||||
rom_direct_upload = 0;
|
||||
#else
|
||||
rom_direct_upload = (core_type & 0x10) >> 4; // bit 4 - direct upload support
|
||||
#endif
|
||||
core_type &= 0xef;
|
||||
|
||||
if((core_type != CORE_TYPE_DUMB) &&
|
||||
@ -874,30 +808,30 @@ void user_io_send_buttons(char force) {
|
||||
|
||||
// frequently poll the adc the switches
|
||||
// and buttons are connected to
|
||||
PollAdc();
|
||||
PollADC();
|
||||
|
||||
unsigned char map = 0;
|
||||
if(adc_state & 1) map |= SWITCH2;
|
||||
if(adc_state & 2) map |= SWITCH1;
|
||||
if(Buttons() & 1) map |= SWITCH2;
|
||||
if(Buttons() & 2) map |= SWITCH1;
|
||||
|
||||
if(adc_state & 4) map |= BUTTON1;
|
||||
else if(adc_state & 8) map |= BUTTON2;
|
||||
if(Buttons() & 4) map |= BUTTON1;
|
||||
else if(Buttons() & 8) map |= BUTTON2;
|
||||
if(kbd_reset) map |= BUTTON2;
|
||||
|
||||
if(!mist_cfg.keep_video_mode) video_altered = 0;
|
||||
if(!mist_cfg.keep_video_mode) VIDEO_ALTERED_VAR = 0;
|
||||
|
||||
if(video_altered & 1)
|
||||
if(VIDEO_ALTERED_VAR & 1)
|
||||
{
|
||||
if(video_sd_disable) map |= CONF_SCANDOUBLER_DISABLE;
|
||||
if(VIDEO_SD_DISABLE_VAR) map |= CONF_SCANDOUBLER_DISABLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(mist_cfg.scandoubler_disable) map |= CONF_SCANDOUBLER_DISABLE;
|
||||
}
|
||||
|
||||
if(video_altered & 2)
|
||||
if(VIDEO_ALTERED_VAR & 2)
|
||||
{
|
||||
if(video_ypbpr) map |= CONF_YPBPR;
|
||||
if(VIDEO_YPBPR_VAR) map |= CONF_YPBPR;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1207,17 +1141,9 @@ void user_io_poll() {
|
||||
}
|
||||
|
||||
// poll db9 joysticks
|
||||
static int joy0_state = JOY0;
|
||||
if((*AT91C_PIOA_PDSR & JOY0) != joy0_state) {
|
||||
joy0_state = *AT91C_PIOA_PDSR & JOY0;
|
||||
unsigned char joy_map = 0;
|
||||
|
||||
unsigned char joy_map = 0;
|
||||
if(!(joy0_state & JOY0_UP)) joy_map |= JOY_UP;
|
||||
if(!(joy0_state & JOY0_DOWN)) joy_map |= JOY_DOWN;
|
||||
if(!(joy0_state & JOY0_LEFT)) joy_map |= JOY_LEFT;
|
||||
if(!(joy0_state & JOY0_RIGHT)) joy_map |= JOY_RIGHT;
|
||||
if(!(joy0_state & JOY0_BTN1)) joy_map |= JOY_BTN1;
|
||||
if(!(joy0_state & JOY0_BTN2)) joy_map |= JOY_BTN2;
|
||||
if(GetDB9(0, &joy_map)) {
|
||||
|
||||
joy_map = virtual_joystick_mapping(0x00db, 0x0000, joy_map);
|
||||
|
||||
@ -1226,18 +1152,7 @@ void user_io_poll() {
|
||||
StateJoySet(joy_map, mist_cfg.joystick_db9_fixed_index ? idx : hid_get_joysticks()); // send to OSD
|
||||
virtual_joystick_keyboard(joy_map);
|
||||
}
|
||||
|
||||
static int joy1_state = JOY1;
|
||||
if((*AT91C_PIOA_PDSR & JOY1) != joy1_state) {
|
||||
joy1_state = *AT91C_PIOA_PDSR & JOY1;
|
||||
|
||||
unsigned char joy_map = 0;
|
||||
if(!(joy1_state & JOY1_UP)) joy_map |= JOY_UP;
|
||||
if(!(joy1_state & JOY1_DOWN)) joy_map |= JOY_DOWN;
|
||||
if(!(joy1_state & JOY1_LEFT)) joy_map |= JOY_LEFT;
|
||||
if(!(joy1_state & JOY1_RIGHT)) joy_map |= JOY_RIGHT;
|
||||
if(!(joy1_state & JOY1_BTN1)) joy_map |= JOY_BTN1;
|
||||
if(!(joy1_state & JOY1_BTN2)) joy_map |= JOY_BTN2;
|
||||
if(GetDB9(1, &joy_map)) {
|
||||
|
||||
joy_map = virtual_joystick_mapping(0x00db, 0x0001, joy_map);
|
||||
|
||||
@ -1662,7 +1577,7 @@ void user_io_poll() {
|
||||
// and toggle scandoubler on/off then
|
||||
static unsigned long timer = 1;
|
||||
static unsigned char ypbpr_toggle = 0;
|
||||
if(user_io_menu_button())
|
||||
if(MenuButton())
|
||||
{
|
||||
if(timer == 1)
|
||||
timer = GetTimer(1000);
|
||||
@ -1676,12 +1591,12 @@ void user_io_poll() {
|
||||
|
||||
user_io_send_buttons(1);
|
||||
OsdDisableMenuButton(1);
|
||||
video_altered |= 1;
|
||||
video_sd_disable = mist_cfg.scandoubler_disable;
|
||||
VIDEO_ALTERED_VAR |= 1;
|
||||
VIDEO_SD_DISABLE_VAR = mist_cfg.scandoubler_disable;
|
||||
}
|
||||
}
|
||||
|
||||
if(adc_state & 8)
|
||||
if(UserButton())
|
||||
{
|
||||
if(!ypbpr_toggle)
|
||||
{
|
||||
@ -1692,8 +1607,8 @@ void user_io_poll() {
|
||||
|
||||
user_io_send_buttons(1);
|
||||
OsdDisableMenuButton(1);
|
||||
video_altered |= 2;
|
||||
video_ypbpr = mist_cfg.ypbpr;
|
||||
VIDEO_ALTERED_VAR |= 2;
|
||||
VIDEO_YPBPR_VAR = mist_cfg.ypbpr;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1711,15 +1626,7 @@ void user_io_poll() {
|
||||
}
|
||||
|
||||
char user_io_dip_switch1() {
|
||||
return(((adc_state & 2)?1:0) || DEBUG_MODE);
|
||||
}
|
||||
|
||||
char user_io_menu_button() {
|
||||
return((adc_state & 4)?1:0);
|
||||
}
|
||||
|
||||
char user_io_user_button() {
|
||||
return((!user_io_menu_button() && (adc_state & 8))?1:0);
|
||||
return(((Buttons() & 2)?1:0) || DEBUG_MODE);
|
||||
}
|
||||
|
||||
static void send_keycode(unsigned short code) {
|
||||
@ -1887,7 +1794,7 @@ static void check_reset(unsigned short modifiers, char useKeys)
|
||||
{
|
||||
if(modifiers & 2) // with lshift - MiST reset
|
||||
{
|
||||
if(mist_cfg.keep_video_mode) video_keep = VIDEO_KEEP_VALUE;
|
||||
if(mist_cfg.keep_video_mode) VIDEO_KEEP_VAR = VIDEO_KEEP_VALUE;
|
||||
MCUReset(); // HW reset
|
||||
for(;;);
|
||||
}
|
||||
|
||||
12
user_io.h
12
user_io.h
@ -168,9 +168,6 @@ char minimig_v1();
|
||||
char minimig_v2();
|
||||
char user_io_is_8bit_with_config_string();
|
||||
void user_io_poll();
|
||||
char user_io_menu_button();
|
||||
char user_io_button_dip_switch1();
|
||||
char user_io_user_button();
|
||||
void user_io_osd_key_enable(char);
|
||||
void user_io_serial_tx(char *, uint16_t);
|
||||
char *user_io_8bit_get_string(char);
|
||||
@ -211,13 +208,4 @@ unsigned char user_io_ext_idx(const char*, const char*);
|
||||
|
||||
void user_io_change_into_core_dir(void);
|
||||
|
||||
|
||||
#define USB_LOAD_VAR *(int*)(0x0020FF04)
|
||||
#define USB_LOAD_VAR *(int*)(0x0020FF04)
|
||||
#define USB_LOAD_VALUE 12345678
|
||||
|
||||
#define DEBUG_MODE_VAR *(int*)(0x0020FF08)
|
||||
#define DEBUG_MODE_VALUE 87654321
|
||||
#define DEBUG_MODE (DEBUG_MODE_VAR == DEBUG_MODE_VALUE)
|
||||
|
||||
#endif // USER_IO_H
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user