Browse Source

Merge pull request #6066 from neiljay/pr/add_mips-pic32_mz

cpu: Add PIC32MZ support
pr/rotary
Hauke Petersen 6 years ago committed by GitHub
parent
commit
76bae4b111
  1. 2
      boards/pic32-wifire/Makefile
  2. 9
      boards/pic32-wifire/Makefile.features
  3. 4
      boards/pic32-wifire/Makefile.include
  4. 58
      boards/pic32-wifire/include/board.h
  5. 62
      boards/pic32-wifire/include/periph_conf.h
  6. 419
      boards/pic32-wifire/pic32_config_settings.c
  7. 45
      boards/pic32-wifire/wifire.c
  8. 43
      cpu/Makefile.include.mips_common
  9. 42
      cpu/mips32r2_common/Makefile.include
  10. 69
      cpu/mips32r2_common/include/eic_irq.h
  11. 48
      cpu/mips32r2_common/periph/timer.c
  12. 2
      cpu/mips_pic32_common/Makefile
  13. 7
      cpu/mips_pic32_common/Makefile.include
  14. 3
      cpu/mips_pic32_common/periph/Makefile
  15. 77
      cpu/mips_pic32_common/periph/uart.c
  16. 244
      cpu/mips_pic32_common/reset_mod.S
  17. 8
      cpu/mips_pic32mz/Makefile
  18. 35
      cpu/mips_pic32mz/Makefile.include
  19. 52
      cpu/mips_pic32mz/eic_pic32mz.c
  20. 54
      cpu/mips_pic32mz/include/cpu.h
  21. 71
      cpu/mips_pic32mz/include/cpu_conf.h
  22. 19
      cpu/mips_pic32mz/include/periph_cpu.h
  23. 51671
      cpu/mips_pic32mz/include/vendor/p32mz2048efg100.h
  24. 409
      cpu/mips_pic32mz/ldscripts/pic32mz2048_uhi.ld
  25. 1
      cpu/mips_pic32mz/p32mz2048efg100/Makefile
  26. 6288
      cpu/mips_pic32mz/p32mz2048efg100/p32mz2048efg100.S
  27. 2
      examples/gnrc_border_router/Makefile
  28. 2
      examples/javascript/Makefile
  29. 4
      sys/posix/include/fcntl.h
  30. 4
      sys/posix/include/sys/statvfs.h

2
boards/pic32-wifire/Makefile

@ -0,0 +1,2 @@
MODULE = board
include $(RIOTBASE)/Makefile.base

9
boards/pic32-wifire/Makefile.features

@ -0,0 +1,9 @@
# Put defined MCU peripherals here (in alphabetical order)
FEATURES_PROVIDED += periph_timer
FEATURES_PROVIDED += periph_uart
# Various other features (if any)
FEATURES_PROVIDED += cpp
# The board MPU family (used for grouping by the CI system)
FEATURES_MCU_GROUP = mips32r2

4
boards/pic32-wifire/Makefile.include

@ -0,0 +1,4 @@
export CPU = mips_pic32mz
export CPU_MODEL=p32mz2048efg100
export INCLUDES += -I$(RIOTBOARD)/$(BOARD)/include/
export APPDEPS += $(RIOTCPU)/$(CPU)/$(CPU_MODEL)/$(CPU_MODEL).S

58
boards/pic32-wifire/include/board.h

@ -0,0 +1,58 @@
/*
* Copyright(C) 2017, Imagination Technologies Limited and/or its
* affiliated group companies.
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
*/
/**
* @defgroup boards_pic32-wifire Digilent PIC32 WiFire
* @ingroup boards
* @brief board configuration for the Digilent PIC32 WiFire
* @details
* See:
* http://store.digilentinc.com/chipkit-wi-fire-wifi-enabled-mz-microcontroller-board/
* for more information on the board.
*
* @{
*
* @file
* @brief board configuration for the Digilent PIC32 WiFire
*
* @author Neil Jones <Neil.Jones@imgtec.com>
*/
#ifndef _BOARD_H_
#define _BOARD_H_
#ifdef __cplusplus
extern "C" {
#endif
#include "vendor/p32mz2048efg100.h"
/**
* @brief Set how many increments of the count register per uS
* needed by the timer code.
*/
#define TICKS_PER_US (100)
/**
* @brief We are using an External Interrupt Controller (all pic32 devices use this mode)
*/
#define EIC_IRQ (1)
/**
* @brief Board level initialisation
*/
void board_init(void);
#ifdef __cplusplus
}
#endif
#endif /* _BOARD_H_ */
/** @} */

62
boards/pic32-wifire/include/periph_conf.h

@ -0,0 +1,62 @@
/*
* Copyright(C) 2016,2017, Imagination Technologies Limited and/or its
* affiliated group companies.
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
*/
/**
* @defgroup boards_pic32-wifire Digilent PIC32 WiFire
* @ingroup boards
* @brief peripheral configuration for the Digilent PIC32 WiFire
* @{
*
* @file
* @brief peripheral configuration for the Digilent PIC32 WiFire
*
* @author Neil Jones <Neil.Jones@imgtec.com>
*/
#ifndef _PERIPH_CONF_H_
#define _PERIPH_CONF_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief The peripheral clock is required for the UART Baud rate calculation
* It is configured by the 'config' registers (see pic32_config_settings.c)
*/
#define PERIPHERAL_CLOCK (100000000) /* Hz */
/**
* @brief Timer definitions
* @{
*/
#define TIMER_NUMOF (1)
#define TIMER_0_CHANNELS (3)
/** @} */
/**
* @brief UART Definitions
* There are 6 UARTS available on this CPU.
* We route debug via UART4 on this board,
* this is the UART connected to the FTDI USB <-> UART device.
*
* Note Microchip number the UARTS 1->4.
* @{
*/
#define UART_NUMOF (6)
#define DEBUG_VIA_UART (4)
#define DEBUG_UART_BAUD (9600)
/** @} */
#ifdef __cplusplus
}
#endif
#endif
/** @} */

419
boards/pic32-wifire/pic32_config_settings.c

@ -0,0 +1,419 @@
/*
* Copyright(C) 2016,2017, Imagination Technologies Limited and/or its
* affiliated group companies.
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
*/
#include <stdint.h>
#include "vendor/p32mz2048efg100.h"
/*
* Note banked access only applies to MZ part MX only has 1 set of registers
* similar to the MZ's lower alias.Thus when working with MX parts comment
* out the *_B* entries, note the address in the comments are different for MX
* too so a different linker script is required between MX and MZ to place
* these registers at the correct addresses. MM parts have completely different
* config registers, so this file is not applicable.
*
* Note when programming via Microchip IPE (tested using a Pickit-3) entries
* need to exist in the programming file for both the lower alias and the
* config1 configuration spaces (starting at 0x1FC0FFC0 and 0x1FC4FFC0)
* hence the duplicate entries in different sections allowing the linker to
* place them at different addresses.
*/
/*
* DEVCFG3_LA @ 0x1FC0FFC0 (lower alias)
* ADEVFGC3_LA @ 0x1FC0FF40 (alternate devcfg3 in lower alias)
* DEVCFG3_B1 @ 0x1FC4FFC0 (config space 1)
* ADEVCFG3_B1 @ 0x1FC4FF40 (alternate devcfg3 in config space 1)
* DEVCFG3_B2 @ 0x1FC6FFC0 (config space 1)
* ADEVCFG3_B2 @ 0x1FC6FF40 (alternate devcfg3 in config space 2)
*
*
* USERID
* FMIIEN OFF Ethernet RMII/MII Enable RMII Enabled
* FETHIO ON Ethernet I/O Pin Select Default Ethernet I/O
* PGL1WAY OFF Permission Group Lock One Way Configuration Allow multiple reconfigurations
* PMDL1WAY OFF Peripheral Module Disable Configuration Allow multiple reconfigurations
* IOL1WAY OFF Peripheral Pin Select Configuration Allow multiple reconfigurations
* FUSBIDIO OFF USB USBID Selection Controlled by Port Function
*/
volatile uint32_t DEVCFG3_LA __attribute__((used, section(".devcfg3_la"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG3_USERID_MASK | 0xFFFF << _DEVCFG3_USERID_POSITION)
& (~_DEVCFG3_FMIIEN_MASK | 0 << _DEVCFG3_FMIIEN_POSITION)
& (~_DEVCFG3_FETHIO_MASK | 1 << _DEVCFG3_FETHIO_POSITION)
& (~_DEVCFG3_PGL1WAY_MASK | 0 << _DEVCFG3_PGL1WAY_POSITION)
& (~_DEVCFG3_PMDL1WAY_MASK | 0 << _DEVCFG3_PMDL1WAY_POSITION)
& (~_DEVCFG3_IOL1WAY_MASK | 0 << _DEVCFG3_IOL1WAY_POSITION)
& (~_DEVCFG3_FUSBIDIO_MASK | 0 << _DEVCFG3_FUSBIDIO_POSITION);
volatile uint32_t ADEVCFG3_LA __attribute__((used, section(".adevcfg3_la"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG3_USERID_MASK | 0xFFFF << _DEVCFG3_USERID_POSITION)
& (~_DEVCFG3_FMIIEN_MASK | 0 << _DEVCFG3_FMIIEN_POSITION)
& (~_DEVCFG3_FETHIO_MASK | 1 << _DEVCFG3_FETHIO_POSITION)
& (~_DEVCFG3_PGL1WAY_MASK | 0 << _DEVCFG3_PGL1WAY_POSITION)
& (~_DEVCFG3_PMDL1WAY_MASK | 0 << _DEVCFG3_PMDL1WAY_POSITION)
& (~_DEVCFG3_IOL1WAY_MASK | 0 << _DEVCFG3_IOL1WAY_POSITION)
& (~_DEVCFG3_FUSBIDIO_MASK | 0 << _DEVCFG3_FUSBIDIO_POSITION);
volatile uint32_t DEVCFG3_B1 __attribute__((used, section(".devcfg3_b1"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG3_USERID_MASK | 0xFFFF << _DEVCFG3_USERID_POSITION)
& (~_DEVCFG3_FMIIEN_MASK | 0 << _DEVCFG3_FMIIEN_POSITION)
& (~_DEVCFG3_FETHIO_MASK | 1 << _DEVCFG3_FETHIO_POSITION)
& (~_DEVCFG3_PGL1WAY_MASK | 0 << _DEVCFG3_PGL1WAY_POSITION)
& (~_DEVCFG3_PMDL1WAY_MASK | 0 << _DEVCFG3_PMDL1WAY_POSITION)
& (~_DEVCFG3_IOL1WAY_MASK | 0 << _DEVCFG3_IOL1WAY_POSITION)
& (~_DEVCFG3_FUSBIDIO_MASK | 0 << _DEVCFG3_FUSBIDIO_POSITION);
volatile uint32_t ADEVCFG3_B1 __attribute__((used, section(".adevcfg3_b1"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG3_USERID_MASK | 0xFFFF << _DEVCFG3_USERID_POSITION)
& (~_DEVCFG3_FMIIEN_MASK | 0 << _DEVCFG3_FMIIEN_POSITION)
& (~_DEVCFG3_FETHIO_MASK | 1 << _DEVCFG3_FETHIO_POSITION)
& (~_DEVCFG3_PGL1WAY_MASK | 0 << _DEVCFG3_PGL1WAY_POSITION)
& (~_DEVCFG3_PMDL1WAY_MASK | 0 << _DEVCFG3_PMDL1WAY_POSITION)
& (~_DEVCFG3_IOL1WAY_MASK | 0 << _DEVCFG3_IOL1WAY_POSITION)
& (~_DEVCFG3_FUSBIDIO_MASK | 0 << _DEVCFG3_FUSBIDIO_POSITION);
/*
* Not needed by default:
* volatile uint32_t DEVCFG3_B2 __attribute__((used,section(".devcfg3_b2")))
* = DEVCFG3_LA;
* volatile uint32_t ADEVCFG3_B2 __attribute__((used,section(".adevcfg3_la")))
* = DEVCFG3_LA;
*
*/
/*
* DEVCFG2_LA @ 0x1FC0FFC4 (lower alias)
* ADEVFGC2_LA @ 0x1FC0FF44 (alternate devcfg2 in lower alias)
* DEVCFG2_B1 @ 0x1FC4FFC4 (config space 1)
* ADEVCFG2_B1 @ 0x1FC4FF44 (alternate devcfg2 in config space 1)
* DEVCFG2_B2 @ 0x1FC6FFC4 (config space 1)
* ADEVCFG2_B2 @ 0x1FC6FF44 (alternate devcfg2 in config space 2)
*
* 24MHz OSC / 3 * 50 / 2 = 200MHz
*
* FPLLIDIV DIV_3 System PLL Input Divider 3x Divider
* FPLLRNG RANGE_5_10_MHZ System PLL Input Range 5-10 MHz Input
* FPLLICLK PLL_POSC System PLL Input Clock Selection POSC is input to the System PLL
* FPLLMULT MUL_50 System PLL Multiplier PLL Multiply by 50
* FPLLODIV DIV_2 System PLL Output Clock Divider 2x Divider
* UPLLFSEL FREQ_24MHZ USB PLL Input Frequency Selection USB PLL input is 24 MHz
*/
volatile uint32_t DEVCFG2_LA __attribute__ ((used, section(".devcfg2_la"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG2_FPLLIDIV_MASK | 2 << _DEVCFG2_FPLLIDIV_POSITION)
& (~_DEVCFG2_FPLLRNG_MASK | 0x1 << _DEVCFG2_FPLLRNG_POSITION)
& (~_DEVCFG2_FPLLICLK_MASK | 0x0 << _DEVCFG2_FPLLICLK_POSITION)
& (~_DEVCFG2_FPLLMULT_MASK | 49 << _DEVCFG2_FPLLMULT_POSITION)
& (~_DEVCFG2_FPLLODIV_MASK | 1 << _DEVCFG2_FPLLODIV_POSITION)
& (~_DEVCFG2_UPLLFSEL_MASK | 0x1 << _DEVCFG2_UPLLFSEL_POSITION);
volatile uint32_t ADEVCFG2_LA __attribute__ ((used, section(".adevcfg2_la"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG2_FPLLIDIV_MASK | 2 << _DEVCFG2_FPLLIDIV_POSITION)
& (~_DEVCFG2_FPLLRNG_MASK | 0x1 << _DEVCFG2_FPLLRNG_POSITION)
& (~_DEVCFG2_FPLLICLK_MASK | 0x0 << _DEVCFG2_FPLLICLK_POSITION)
& (~_DEVCFG2_FPLLMULT_MASK | 49 << _DEVCFG2_FPLLMULT_POSITION)
& (~_DEVCFG2_FPLLODIV_MASK | 1 << _DEVCFG2_FPLLODIV_POSITION)
& (~_DEVCFG2_UPLLFSEL_MASK | 0x1 << _DEVCFG2_UPLLFSEL_POSITION);
volatile uint32_t DEVCFG2_B1 __attribute__ ((used, section(".devcfg2_b1"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG2_FPLLIDIV_MASK | 2 << _DEVCFG2_FPLLIDIV_POSITION)
& (~_DEVCFG2_FPLLRNG_MASK | 0x1 << _DEVCFG2_FPLLRNG_POSITION)
& (~_DEVCFG2_FPLLICLK_MASK | 0x0 << _DEVCFG2_FPLLICLK_POSITION)
& (~_DEVCFG2_FPLLMULT_MASK | 49 << _DEVCFG2_FPLLMULT_POSITION)
& (~_DEVCFG2_FPLLODIV_MASK | 1 << _DEVCFG2_FPLLODIV_POSITION)
& (~_DEVCFG2_UPLLFSEL_MASK | 0x1 << _DEVCFG2_UPLLFSEL_POSITION);
volatile uint32_t ADEVCFG2_B1 __attribute__ ((used, section(".adevcfg2_b1"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG2_FPLLIDIV_MASK | 2 << _DEVCFG2_FPLLIDIV_POSITION)
& (~_DEVCFG2_FPLLRNG_MASK | 0x1 << _DEVCFG2_FPLLRNG_POSITION)
& (~_DEVCFG2_FPLLICLK_MASK | 0x0 << _DEVCFG2_FPLLICLK_POSITION)
& (~_DEVCFG2_FPLLMULT_MASK | 49 << _DEVCFG2_FPLLMULT_POSITION)
& (~_DEVCFG2_FPLLODIV_MASK | 1 << _DEVCFG2_FPLLODIV_POSITION)
& (~_DEVCFG2_UPLLFSEL_MASK | 0x1 << _DEVCFG2_UPLLFSEL_POSITION);
/* Not needed by default: */
/* uint32_t DEVCFG2_B2 __attribute__ ((section(".devcfg2_b2"))) = DEVCFG2_LA; */
/* uint32_t ADEVCFG2_B2 __attribute__ ((section(".adevcfg2_b2"))) = DEVCFG2_LA; */
/*
* DEVCFG1_LA @ 0x1FC0FFC8 (lower alias)
* ADEVFGC1_LA @ 0x1FC0FF48 (alternate devcfg1 in lower alias)
* DEVCFG1_B1 @ 0x1FC4FFC8 (config space 1)
* ADEVCFG1_B1 @ 0x1FC4FF48 (alternate devcfg1 in config space 1)
* DEVCFG1_B2 @ 0x1FC6FFC8 (config space 1)
* ADEVCFG1_B2 @ 0x1FC6FF48 (alternate devcfg1 in config space 2)
*
* FNOSC SPLL Oscillator Selection Bits System PLL
* DMTINTV WIN_127_128 DMT Count Window Interval Window/Interval value is 127/128 counter value
* FSOSCEN OFF Secondary Oscillator Enable Disable SOSC
* IESO ON Internal/External Switch Over Enabled
* POSCMOD EC Primary Oscillator Configuration External clock mode
* OSCIOFNC OFF CLKO Output Signal Active on the OSCO Pin Disabled (1)
* FCKSM CSDCMD Clock Switching and Monitor Selection Clock Switch Disabled, FSCM Disabled
* WDTPS PS1048576 Watchdog Timer Postscaler 1:1048576
* WDTSPGM STOP Watchdog Timer Stop During Flash Programming WDT stops during Flash programming
* WINDIS NORMAL Watchdog Timer Window Mode Watchdog Timer is in non-Window mode
* FWDTEN OFF Watchdog Timer Enable WDT Disabled
* FWDTWINSZ WINSZ_25 Watchdog Timer Window Size Window size is 25%
* DMTCNT DMT8 Deadman Timer Count Selection 2^8 (256)
* FDMTEN OFF Deadman Timer Enable Deadman Timer is disabled
*/
volatile uint32_t DEVCFG1_LA __attribute__ ((used, section(".devcfg1_la"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG1_FNOSC_MASK | 0x1 << _DEVCFG1_FNOSC_POSITION)
& (~_DEVCFG1_DMTINTV_MASK | 0x7 << _DEVCFG1_DMTINTV_POSITION)
& (~_DEVCFG1_FSOSCEN_MASK | 0 << _DEVCFG1_FSOSCEN_POSITION)
& (~_DEVCFG1_IESO_MASK | 1 << _DEVCFG1_IESO_POSITION)
& (~_DEVCFG1_POSCMOD_MASK | 0x0 << _DEVCFG1_POSCMOD_POSITION)
& (~_DEVCFG1_OSCIOFNC_MASK | 1 << _DEVCFG1_OSCIOFNC_POSITION)
& (~_DEVCFG1_FCKSM_MASK | 0x0 << _DEVCFG1_FCKSM_POSITION)
& (~_DEVCFG1_WDTPS_MASK | 0x14 << _DEVCFG1_WDTPS_POSITION)
& (~_DEVCFG1_WDTSPGM_MASK | 1 << _DEVCFG1_WDTSPGM_POSITION)
& (~_DEVCFG1_WINDIS_MASK | 1 << _DEVCFG1_WINDIS_POSITION)
& (~_DEVCFG1_FWDTEN_MASK | 0 << _DEVCFG1_FWDTEN_POSITION)
& (~_DEVCFG1_FWDTWINSZ_MASK | 0x3 << _DEVCFG1_FWDTWINSZ_POSITION)
& (~_DEVCFG1_DMTCNT_MASK | 0x0 << _DEVCFG1_DMTCNT_POSITION)
& (~_DEVCFG1_FDMTEN_MASK | 0 << _DEVCFG1_FDMTEN_POSITION);
volatile uint32_t ADEVCFG1_LA __attribute__ ((used, section(".adevcfg1_la"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG1_FNOSC_MASK | 0x1 << _DEVCFG1_FNOSC_POSITION)
& (~_DEVCFG1_DMTINTV_MASK | 0x7 << _DEVCFG1_DMTINTV_POSITION)
& (~_DEVCFG1_FSOSCEN_MASK | 0 << _DEVCFG1_FSOSCEN_POSITION)
& (~_DEVCFG1_IESO_MASK | 1 << _DEVCFG1_IESO_POSITION)
& (~_DEVCFG1_POSCMOD_MASK | 0x0 << _DEVCFG1_POSCMOD_POSITION)
& (~_DEVCFG1_OSCIOFNC_MASK | 1 << _DEVCFG1_OSCIOFNC_POSITION)
& (~_DEVCFG1_FCKSM_MASK | 0x0 << _DEVCFG1_FCKSM_POSITION)
& (~_DEVCFG1_WDTPS_MASK | 0x14 << _DEVCFG1_WDTPS_POSITION)
& (~_DEVCFG1_WDTSPGM_MASK | 1 << _DEVCFG1_WDTSPGM_POSITION)
& (~_DEVCFG1_WINDIS_MASK | 1 << _DEVCFG1_WINDIS_POSITION)
& (~_DEVCFG1_FWDTEN_MASK | 0 << _DEVCFG1_FWDTEN_POSITION)
& (~_DEVCFG1_FWDTWINSZ_MASK | 0x3 << _DEVCFG1_FWDTWINSZ_POSITION)
& (~_DEVCFG1_DMTCNT_MASK | 0x0 << _DEVCFG1_DMTCNT_POSITION)
& (~_DEVCFG1_FDMTEN_MASK | 0 << _DEVCFG1_FDMTEN_POSITION);
volatile uint32_t DEVCFG1_B1 __attribute__ ((used, section(".devcfg1_b1"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG1_FNOSC_MASK | 0x1 << _DEVCFG1_FNOSC_POSITION)
& (~_DEVCFG1_DMTINTV_MASK | 0x7 << _DEVCFG1_DMTINTV_POSITION)
& (~_DEVCFG1_FSOSCEN_MASK | 0 << _DEVCFG1_FSOSCEN_POSITION)
& (~_DEVCFG1_IESO_MASK | 1 << _DEVCFG1_IESO_POSITION)
& (~_DEVCFG1_POSCMOD_MASK | 0x0 << _DEVCFG1_POSCMOD_POSITION)
& (~_DEVCFG1_OSCIOFNC_MASK | 1 << _DEVCFG1_OSCIOFNC_POSITION)
& (~_DEVCFG1_FCKSM_MASK | 0x0 << _DEVCFG1_FCKSM_POSITION)
& (~_DEVCFG1_WDTPS_MASK | 0x14 << _DEVCFG1_WDTPS_POSITION)
& (~_DEVCFG1_WDTSPGM_MASK | 1 << _DEVCFG1_WDTSPGM_POSITION)
& (~_DEVCFG1_WINDIS_MASK | 1 << _DEVCFG1_WINDIS_POSITION)
& (~_DEVCFG1_FWDTEN_MASK | 0 << _DEVCFG1_FWDTEN_POSITION)
& (~_DEVCFG1_FWDTWINSZ_MASK | 0x3 << _DEVCFG1_FWDTWINSZ_POSITION)
& (~_DEVCFG1_DMTCNT_MASK | 0x0 << _DEVCFG1_DMTCNT_POSITION)
& (~_DEVCFG1_FDMTEN_MASK | 0 << _DEVCFG1_FDMTEN_POSITION);
volatile uint32_t ADEVCFG1_B1 __attribute__ ((used, section(".adevcfg1_b1"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG1_FNOSC_MASK | 0x1 << _DEVCFG1_FNOSC_POSITION)
& (~_DEVCFG1_DMTINTV_MASK | 0x7 << _DEVCFG1_DMTINTV_POSITION)
& (~_DEVCFG1_FSOSCEN_MASK | 0 << _DEVCFG1_FSOSCEN_POSITION)
& (~_DEVCFG1_IESO_MASK | 1 << _DEVCFG1_IESO_POSITION)
& (~_DEVCFG1_POSCMOD_MASK | 0x0 << _DEVCFG1_POSCMOD_POSITION)
& (~_DEVCFG1_OSCIOFNC_MASK | 1 << _DEVCFG1_OSCIOFNC_POSITION)
& (~_DEVCFG1_FCKSM_MASK | 0x0 << _DEVCFG1_FCKSM_POSITION)
& (~_DEVCFG1_WDTPS_MASK | 0x14 << _DEVCFG1_WDTPS_POSITION)
& (~_DEVCFG1_WDTSPGM_MASK | 1 << _DEVCFG1_WDTSPGM_POSITION)
& (~_DEVCFG1_WINDIS_MASK | 1 << _DEVCFG1_WINDIS_POSITION)
& (~_DEVCFG1_FWDTEN_MASK | 0 << _DEVCFG1_FWDTEN_POSITION)
& (~_DEVCFG1_FWDTWINSZ_MASK | 0x3 << _DEVCFG1_FWDTWINSZ_POSITION)
& (~_DEVCFG1_DMTCNT_MASK | 0x0 << _DEVCFG1_DMTCNT_POSITION)
& (~_DEVCFG1_FDMTEN_MASK | 0 << _DEVCFG1_FDMTEN_POSITION);
/* Not needed by default: */
/* uint32_t DEVCFG1_B2 __attribute__ ((section(".devcfg1_b2"))) = DEVCFG1_LA; */
/* uint32_t ADEVCFG1_B2 __attribute__ ((section(".adevcfg1_b2"))) = DEVCFG1_LA */
/*
* DEVCFG0_LA @ 0x1FC0FFCC (lower alias)
* ADEVFGC0_LA @ 0x1FC0FF4C (alternate devcfg0 in lower alias)
* DEVCFG0_B1 @ 0x1FC4FFCC (config space 1)
* ADEVCFG0_B1 @ 0x1FC4FF4C (alternate devcfg0 in config space 1)
* DEVCFG0_B2 @ 0x1FC6FFCC (config space 1)
* ADEVCFG0_B2 @ 0x1FC6FF4C (alternate devcfg0 in config space 2)
*
* DEBUG OFF Background Debugger Enable Debugger is disabled
* JTAGEN ON JTAG Enable JTAG Port Enabled
* ICESEL ICS_PGx2 ICE/ICD Comm Channel Select Communicate on PGEC2/PGED2
* TRCEN ON Trace Enable Trace features in the CPU are disabled
* BOOTISA MIPS32 Boot ISA Selection Boot code and Exception code is MIPS32
* FECCCON OFF_UNLOCKED Dynamic Flash ECC Configuration ECC and Dynamic ECC are disabled (ECCCON bits are writable)
* FSLEEP OFF Flash Sleep Mode Flash is powered down when the device is in Sleep mode
* DBGPER PG_ALL Debug Mode CPU Access Permission Allow CPU access to all permission regions
* SMCLR MCLR_NORM Soft Master Clear Enable bit MCLR pin generates a normal system Reset
* SOSCGAIN GAIN_2X Secondary Oscillator Gain Control bits 2x gain setting
* SOSCBOOST ON Secondary Oscillator Boost Kick Start Enable bit Boost the kick start of the oscillator
* POSCGAIN GAIN_2X Primary Oscillator Gain Control bits 2x gain setting
* POSCBOOST ON Primary Oscillator Boost Kick Start Enable bit Boost the kick start of the oscillator
* EJTAGBEN NORMAL EJTAG Boot Normal EJTAG functionality
*/
volatile uint32_t DEVCFG0_LA __attribute__ ((used, section(".devcfg0_la"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG0_DEBUG_MASK | 0x3 << _DEVCFG0_DEBUG_POSITION)
& (~_DEVCFG0_JTAGEN_MASK | 0x1 << _DEVCFG0_JTAGEN_POSITION)
& (~_DEVCFG0_ICESEL_MASK | 0x2 << _DEVCFG0_ICESEL_POSITION)
& (~_DEVCFG0_TRCEN_MASK | 0x1 << _DEVCFG0_TRCEN_POSITION)
& (~_DEVCFG0_BOOTISA_MASK | 0x1 << _DEVCFG0_BOOTISA_POSITION)
& (~_DEVCFG0_FECCCON_MASK | 0x3 << _DEVCFG0_FECCCON_POSITION)
& (~_DEVCFG0_FSLEEP_MASK | 0x1 << _DEVCFG0_FSLEEP_POSITION)
& (~_DEVCFG0_DBGPER_MASK | 0x7 << _DEVCFG0_DBGPER_POSITION)
& (~_DEVCFG0_SMCLR_MASK | 0x1 << _DEVCFG0_SMCLR_POSITION)
& (~_DEVCFG0_SOSCGAIN_MASK | 0x2 << _DEVCFG0_SOSCGAIN_POSITION)
& (~_DEVCFG0_SOSCBOOST_MASK | 0x1 << _DEVCFG0_SOSCBOOST_POSITION)
& (~_DEVCFG0_POSCGAIN_MASK | 0x2 << _DEVCFG0_POSCGAIN_POSITION)
& (~_DEVCFG0_POSCBOOST_MASK | 0x1 << _DEVCFG0_POSCBOOST_POSITION)
& (~_DEVCFG0_EJTAGBEN_MASK | 0x1 << _DEVCFG0_EJTAGBEN_POSITION);
volatile uint32_t ADEVCFG0_LA __attribute__ ((used, section(".adevcfg0_la"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG0_DEBUG_MASK | 0x3 << _DEVCFG0_DEBUG_POSITION)
& (~_DEVCFG0_JTAGEN_MASK | 0x1 << _DEVCFG0_JTAGEN_POSITION)
& (~_DEVCFG0_ICESEL_MASK | 0x2 << _DEVCFG0_ICESEL_POSITION)
& (~_DEVCFG0_TRCEN_MASK | 0x1 << _DEVCFG0_TRCEN_POSITION)
& (~_DEVCFG0_BOOTISA_MASK | 0x1 << _DEVCFG0_BOOTISA_POSITION)
& (~_DEVCFG0_FECCCON_MASK | 0x3 << _DEVCFG0_FECCCON_POSITION)
& (~_DEVCFG0_FSLEEP_MASK | 0x1 << _DEVCFG0_FSLEEP_POSITION)
& (~_DEVCFG0_DBGPER_MASK | 0x7 << _DEVCFG0_DBGPER_POSITION)
& (~_DEVCFG0_SMCLR_MASK | 0x1 << _DEVCFG0_SMCLR_POSITION)
& (~_DEVCFG0_SOSCGAIN_MASK | 0x2 << _DEVCFG0_SOSCGAIN_POSITION)
& (~_DEVCFG0_SOSCBOOST_MASK | 0x1 << _DEVCFG0_SOSCBOOST_POSITION)
& (~_DEVCFG0_POSCGAIN_MASK | 0x2 << _DEVCFG0_POSCGAIN_POSITION)
& (~_DEVCFG0_POSCBOOST_MASK | 0x1 << _DEVCFG0_POSCBOOST_POSITION)
& (~_DEVCFG0_EJTAGBEN_MASK | 0x1 << _DEVCFG0_EJTAGBEN_POSITION);
volatile uint32_t DEVCFG0_B1 __attribute__ ((used, section(".devcfg0_b1"))) =
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG0_DEBUG_MASK | 0x3 << _DEVCFG0_DEBUG_POSITION)
& (~_DEVCFG0_JTAGEN_MASK | 0x1 << _DEVCFG0_JTAGEN_POSITION)
& (~_DEVCFG0_ICESEL_MASK | 0x2 << _DEVCFG0_ICESEL_POSITION)
& (~_DEVCFG0_TRCEN_MASK | 0x1 << _DEVCFG0_TRCEN_POSITION)
& (~_DEVCFG0_BOOTISA_MASK | 0x1 << _DEVCFG0_BOOTISA_POSITION)
& (~_DEVCFG0_FECCCON_MASK | 0x3 << _DEVCFG0_FECCCON_POSITION)
& (~_DEVCFG0_FSLEEP_MASK | 0x1 << _DEVCFG0_FSLEEP_POSITION)
& (~_DEVCFG0_DBGPER_MASK | 0x7 << _DEVCFG0_DBGPER_POSITION)
& (~_DEVCFG0_SMCLR_MASK | 0x1 << _DEVCFG0_SMCLR_POSITION)
& (~_DEVCFG0_SOSCGAIN_MASK | 0x2 << _DEVCFG0_SOSCGAIN_POSITION)
& (~_DEVCFG0_SOSCBOOST_MASK | 0x1 << _DEVCFG0_SOSCBOOST_POSITION)
& (~_DEVCFG0_POSCGAIN_MASK | 0x2 << _DEVCFG0_POSCGAIN_POSITION)
& (~_DEVCFG0_POSCBOOST_MASK | 0x1 << _DEVCFG0_POSCBOOST_POSITION)
& (~_DEVCFG0_EJTAGBEN_MASK | 0x1 << _DEVCFG0_EJTAGBEN_POSITION);
volatile uint32_t ADEVCFG0_B1 __attribute__ ((used, section(".adevcfg0_b1")))=
0xffffffff /* unused bits must be 1 */
& (~_DEVCFG0_DEBUG_MASK | 0x3 << _DEVCFG0_DEBUG_POSITION)
& (~_DEVCFG0_JTAGEN_MASK | 0x1 << _DEVCFG0_JTAGEN_POSITION)
& (~_DEVCFG0_ICESEL_MASK | 0x2 << _DEVCFG0_ICESEL_POSITION)
& (~_DEVCFG0_TRCEN_MASK | 0x1 << _DEVCFG0_TRCEN_POSITION)
& (~_DEVCFG0_BOOTISA_MASK | 0x1 << _DEVCFG0_BOOTISA_POSITION)
& (~_DEVCFG0_FECCCON_MASK | 0x3 << _DEVCFG0_FECCCON_POSITION)
& (~_DEVCFG0_FSLEEP_MASK | 0x1 << _DEVCFG0_FSLEEP_POSITION)
& (~_DEVCFG0_DBGPER_MASK | 0x7 << _DEVCFG0_DBGPER_POSITION)
& (~_DEVCFG0_SMCLR_MASK | 0x1 << _DEVCFG0_SMCLR_POSITION)
& (~_DEVCFG0_SOSCGAIN_MASK | 0x2 << _DEVCFG0_SOSCGAIN_POSITION)
& (~_DEVCFG0_SOSCBOOST_MASK | 0x1 << _DEVCFG0_SOSCBOOST_POSITION)
& (~_DEVCFG0_POSCGAIN_MASK | 0x2 << _DEVCFG0_POSCGAIN_POSITION)
& (~_DEVCFG0_POSCBOOST_MASK | 0x1 << _DEVCFG0_POSCBOOST_POSITION)
& (~_DEVCFG0_EJTAGBEN_MASK | 0x1 << _DEVCFG0_EJTAGBEN_POSITION);
/*
* uint32_t DEVCFG0_B2 __attribute__ ((section(".devcfg0_b2")))
* = 0xFFFFF7D7;
* uint32_t ADEVCFG0_B2 __attribute__ ((section(".adevcfg0_b2")))
* = 0xFFFFF7D7;
*
*/
/*
* DEVCP0_LA @ 0x1FC0FFDC (lower alias)
* ADEVCP0_LA @ 0x1FC0FF5C (alternate devcp0 in lower alias)
* DEVCP0_B1 @ 0x1FC4FFDC (config space 1)
* ADEVCP0_B1 @ 0x1FC4FF5C (alternate devcp0 in config space 1)
* DEVCP0_B2 @ 0x1FC6FFDC (config space 1)
* ADEVCP0_B2 @ 0x1FC6FF5C (alternate devcp0 in config space 2
*
* CP OFF Code Protect Protection Disabled, unused bits must be 1.
*/
volatile uint32_t DEVCP0_LA __attribute__ ((used, section(".devcp0_la"))) =
0xFFFFFFFF | _DEVCP0_CP_MASK;
volatile uint32_t ADEVCP0_LA __attribute__ ((used, section(".adevcp0_la"))) =
0xFFFFFFFF | _DEVCP0_CP_MASK;
volatile uint32_t DEVCP0_B1 __attribute__ ((used, section(".devcp0_b1"))) =
0xFFFFFFFF | _DEVCP0_CP_MASK;
volatile uint32_t ADEVCP0_B1 __attribute__ ((used, section(".adevcp0_b1"))) =
0xFFFFFFFF | _DEVCP0_CP_MASK;
/* not needed by default */
/* uint32_t DEVCP0_B2 __attribute__ ((section(".devcp0_b1"))) = 0xFFFFFFFF; */
/* uint32_t ADEVCP0_B2 __attribute__ ((section(".adevcp0_b1"))) = 0xFFFFFFFF; */
/*
* SEQ_B1[0..3] @ 1FC0FFF0
* SEQ_B1[0..3] @ 1FC4FFF0
*
* TSEQ Boot Flash True Sequence Number
* CSEQ Boot Flash Complement Sequence Number
*/
volatile uint32_t SEQ_LA[4] __attribute__ ((used, section(".seq_la"))) =
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
volatile uint32_t SEQ_B1[4] __attribute__ ((used, section(".seq_b1"))) =
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
/*
* Not needed by default:
* uint32_t SEQ_B2[4] __attribute__ ((section(".seq_b2"))) =
* {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF};
*/
/*
* STUPIDLY Microchip has hard coded the MSB bit of devsign to 0, So even if
* you erase the whole device, everything returns 0xFFFFFFF except this 1
* register (and its alternate) which return 0x7FFFFFF!!
*
* We set it in the output image so verification doesn't fail
*
* DEVSIGN0 @ 0xBFC0FFEC
* ADEVSIGN0 @ 0xBFC0FF6C
*
*/
volatile uint32_t DEVSIGN_LA __attribute__ ((used, section(".devsign_la"))) = 0x7FFFFFFF;
volatile uint32_t ADEVSIGN_LA __attribute__ ((used, section(".adevsign_la"))) = 0x7FFFFFFF;
volatile uint32_t DEVSIGN_B1 __attribute__ ((used, section(".devsign_b1"))) = 0x7FFFFFFF;
volatile uint32_t ADEVSIGN_B1 __attribute__ ((used, section(".adevsign_b1"))) = 0x7FFFFFFF;
volatile uint32_t DEVSIGN_B2 __attribute__ ((used, section(".devsign_b2"))) = 0x7FFFFFFF;
volatile uint32_t ADEVSIGN_B2 __attribute__ ((used, section(".adevsign_b2"))) = 0x7FFFFFFF;
/*
* Without a reference to this function from elsewhere LD throws the whole
* compile unit away even though the data is 'volatile' and 'used' !!!
*/
void dummy(void)
{
(void)1;
}

45
boards/pic32-wifire/wifire.c

@ -0,0 +1,45 @@
/*
* Copyright(C) 2016,2017, Imagination Technologies Limited and/or its
* affiliated group companies.
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
*/
#include <stdio.h>
#include <stdint.h>
#include "periph/uart.h"
#include "bitarithm.h"
#include "board.h"
#include "periph_conf.h"
extern void dummy(void);
void board_init(void)
{
/*
* Setup pin mux for UART4 this is the one connected
* to the ftdi chip (usb<->uart)
*/
U4RXREG = 0xb; /* connect pin RPF2 to UART 4 RX */
RPF8R = 0x2; /* connect pin RPF8 to UART 4 TX */
PORTFCLR = BIT8 | BIT2; /* clear down port F pins 2 and 8 */
TRISFCLR = BIT2; /* set portf pin 2 as input */
TRISFSET = BIT8; /* set portf pin 8 as output */
ODCFCLR = BIT8 | BIT2; /* set portf pint 2 and 8 as not open-drain */
/* intialise UART used for debug (printf) */
#ifdef DEBUG_VIA_UART
uart_init(DEBUG_VIA_UART, DEBUG_UART_BAUD, NULL, 0);
#endif
/* Stop the linker from throwing away the PIC32 config register settings */
dummy();
}
void pm_reboot(void)
{
/* TODO, note this is needed to get 'default' example to build */
}

43
cpu/Makefile.include.mips_common

@ -0,0 +1,43 @@
ifndef MIPS_ELF_ROOT
ifneq ($(BUILD_IN_DOCKER),1) #Don't error when BUILD_IN_DOCKER=1 as it _is_ set in DOCKER
$(error "Please set $$(MIPS_ELF_ROOT) and ensure $$(MIPS_ELF_ROOT)/bin is on your PATH")
endif
endif
# Target triple for the build.
export TARGET_ARCH ?= mips-mti-elf
export ABI=32
ifneq ($(BUILD_IN_DOCKER),1) #Don't error when BUILD_IN_DOCKER=1 as MIPS_ELF_ROOT _is_ set in DOCKER
include $(MIPS_ELF_ROOT)/share/mips/rules/mipshal.mk
endif
# define build specific options
export CFLAGS_CPU = -EL -std=gnu99
export CFLAGS_LINK = -ffunction-sections -fno-builtin -fshort-enums #-fdata-sections
export CFLAGS_DBG = -O0 -g2
export CFLAGS_OPT = -Os -g2
export CFLAGS += $(CFLAGS_CPU) $(CFLAGS_LINK) $(CFLAGS_OPT)
#$(CFLAGS_DBG)
ifeq ($(USE_HARD_FLOAT),1)
export CFLAGS += -mhard-float
else
export CFLAGS += -msoft-float #hard-float is the default so we must set soft-float
export LINKFLAGS += -msoft-float
endif
ifeq ($(USE_DSP),1)
export CFLAGS += -mdsp
endif
export ASFLAGS += $(CFLAGS_CPU) $(CFLAGS_OPT) #$(CFLAGS_DBG)
export LINKFLAGS += $(MIPS_HAL_LDFLAGS) -mabi=$(ABI)
export LINKFLAGS += $(CFLAGS_CPU) $(CFLAGS_DBG) $(CFLAGS_OPT)
export LINKFLAGS += -Wl,--gc-sections
# This CPU implementation is using the new core/CPU interface:
export CFLAGS += -DCOREIF_NG=1

42
cpu/mips32r2_common/Makefile.include

@ -1,48 +1,8 @@
ifndef MIPS_ELF_ROOT
$(error "Please set $$(MIPS_ELF_ROOT) and ensure $$(MIPS_ELF_ROOT)/bin is on your PATH")
endif
# Target triple for the build.
export TARGET_ARCH ?= mips-mti-elf
export ABI=32
export MEMORY_BASE=0x80000000
export MEMORY_SIZE=1M
export APP_START=0x80000000
include $(MIPS_ELF_ROOT)/share/mips/rules/mipshal.mk
# define build specific options
export CFLAGS_CPU = -EL -march=mips32r2 -std=gnu99
export CFLAGS_LINK = -ffunction-sections -fdata-sections -fno-builtin -fshort-enums
export CFLAGS_DBG = -O0 -g2
export CFLAGS_OPT = -Os -g2
export CFLAGS += $(CFLAGS_CPU) $(CFLAGS_LINK) $(CFLAGS_OPT)
#$(CFLAGS_DBG)
ifeq ($(USE_HARD_FLOAT),1)
export CFLAGS += -mhard-float
else
export CFLAGS += -msoft-float #hard-float is the default so we must set soft-float
export LINKFLAGS += -msoft-float
endif
include $(RIOTCPU)/Makefile.include.mips_common
ifeq ($(USE_DSP),1)
export CFLAGS += -mdsp
endif
export ASFLAGS += $(CFLAGS_CPU) $(CFLAGS_OPT) #$(CFLAGS_DBG)
export LINKFLAGS += $(MIPS_HAL_LDFLAGS) -mabi=$(ABI)
export LINKFLAGS += -Tuhi32.ld
export LINKFLAGS += $(CFLAGS_CPU) $(CFLAGS_DBG) $(CFLAGS_OPT)
export LINKFLAGS += -Wl,--gc-sections
# This CPU implementation is using the new core/CPU interface:
export CFLAGS += -DCOREIF_NG=1
# use newlib as libc, Actually use toolchains newlib.
#export USEMODULE += newlib
export USEMODULE += periph

69
cpu/mips32r2_common/include/eic_irq.h

@ -0,0 +1,69 @@
/*
* Copyright 2016, Imagination Technologies Limited and/or its
* affiliated group companies.
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup cpu_mips32r2_commom MIPS32R2 Common
* @ingroup cpu
* @{
*
* @file
* @brief API for supporting External Interrupt Controllers (EIC mode)
*
* @author Neil Jones <neil.jones@imgtec.com>
*/
#ifndef EIC_IRQ_H_
#define EIC_IRQ_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @ brief Internal Interrupt numbers
*
* MIPS cores have a few internally generated interrupts from the Timer,
* Performance Counters and Fast Debug Channel hardware, in EIC mode these
* become outputs from the core and are connected to the external controller,
* the external control then loops these back at whichever IPL it decides
*
* We use negative numbers to represent these, leaving positive numbers free for
* the SoC specific interrupts
* @{
*/
#define EIC_IRQ_TIMER (-1)
#define EIC_IRQ_FDC (-2)
#define EIC_IRQ_PC (-3)
/** @} */
/**
* @brief Configure and route the interrupt
*/
void eic_irq_configure(int irq_num);
/**
* @brief Enable an interrupt
*/
void eic_irq_enable(int irq_num);
/**
* @brief Disable an interrupt
*/
void eic_irq_disable(int irq_num);
/**
* @brief Acknowledge an interrupt
*/
void eic_irq_ack(int irq_num);
#ifdef __cplusplus
}
#endif
#endif
/** @} */

48
cpu/mips32r2_common/periph/timer.c

@ -21,9 +21,12 @@
#include "irq.h"
#include "timex.h"
#include "div.h"
#include <sys/time.h>
#ifdef EIC_IRQ
#include "../include/eic_irq.h"
#endif
/*
* setting TIMER_ACCURACY_SHIFT lower will improve accuracy
* at the cost of more regular interrupts (hence less power efficient).
@ -40,7 +43,8 @@
/*
* The base MIPS count / compare timer is fixed frequency at core clock / 2
* and is pretty basic This timer is currently only supported in Vectored
* Interrupt Mode (VI), EIC mode is not supported yet.
* Interrupt Mode (VI), EIC mode is partially supported in non-vectored mode
* only.
*
* RIOT's xtimer expects the timer to operate at 1MHZ or any 2^n multiple or
* factor of this, thus we maintain a software timer which counts at 1MHz.
@ -76,7 +80,7 @@ int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
{
assert(dev == 0);
(void)freq; /*Cannot adjust Frequency */
(void)freq; /* Cannot adjust Frequency */
timer_isr_ctx.cb = cb;
timer_isr_ctx.arg = arg;
@ -93,7 +97,11 @@ int timer_init(tim_t dev, unsigned long freq, timer_cb_t cb, void *arg)
mips32_bc_c0(C0_CAUSE, CR_DC);
/* Enable Timer Interrupts */
#ifdef EIC_IRQ
eic_irq_configure(EIC_IRQ_TIMER);
#else
mips32_bs_c0(C0_STATUS, SR_HINT5);
#endif
return 0;
@ -160,20 +168,52 @@ void timer_stop(tim_t dev)
void timer_irq_enable(tim_t dev)
{
#ifdef EIC_IRQ
eic_irq_enable(EIC_IRQ_TIMER);
#else
mips32_bs_c0(C0_STATUS, SR_HINT5);
#endif
}
void timer_irq_disable(tim_t dev)
{
#ifdef EIC_IRQ
eic_irq_disable(EIC_IRQ_TIMER);
#else
mips32_bc_c0(C0_STATUS, SR_HINT5);
#endif
}
/* note Compiler inserts GP context save + restore code (to current stack). */
#ifdef EIC_IRQ
/*
* This is a hack - currently the toolchain does not support correct placement
* of EIC mode vectors (it is coming though) But we can support non-vectored EIC
* mode and note the default PIC32 interrupt controller (which uses EIC +
* MCU-ASE) defaults to non vectored mode anyway with all interrupts coming via
* vector 0 which is equivalent to 'sw0' in 'VI' mode.
*
* Thus all EIC interrupts should be decoded here (currently only Timer is
* used)
*
* When toolchain support is available we could move to full vector mode but
* this does take up significant space (MCU-ASE provides 256 vectors at 32B
* spacing (the default) thats 8KB of vector space!), So a single entry point
* may be better anyway.
*
*/
void __attribute__ ((interrupt("vector=sw0"), keep_interrupts_masked)) _mips_isr_sw0(void)
#else
void __attribute__ ((interrupt("vector=hw5"))) _mips_isr_hw5(void)
#endif
{
register int cr = mips_getcr();
if (cr & CR_TI) {
#ifdef EIC_IRQ
eic_irq_ack(EIC_IRQ_TIMER);
#endif
uint32_t status = irq_arch_disable();
counter += TIMER_ACCURACY;
irq_arch_restore(status);

2
cpu/mips_pic32_common/Makefile

@ -0,0 +1,2 @@
DIRS += periph
include $(RIOTBASE)/Makefile.base

7
cpu/mips_pic32_common/Makefile.include

@ -0,0 +1,7 @@
# depends on mips32r2_common
USEMODULE += mips32r2_common
export MIPS32R2_COMMON = $(RIOTCPU)/mips32r2_common/
export INCLUDES = $(MIPS32R2_COMMON)include
include $(MIPS32R2_COMMON)Makefile.include

3
cpu/mips_pic32_common/periph/Makefile

@ -0,0 +1,3 @@
MODULE = periph
include $(RIOTBASE)/Makefile.base

77
cpu/mips_pic32_common/periph/uart.c

@ -0,0 +1,77 @@
/*
* Copyright(C) 2016,2017 Imagination Technologies Limited and/or its
* affiliated group companies.
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
*/
#include <assert.h>
#include "periph/uart.h"
#include "board.h"
#define UxMODE(U) (U.regs[0x00/4])
#define UxMODECLR(U) (U.regs[0x04/4])
#define UxMODESET(U) (U.regs[0x08/4])
#define UxSTA(U) (U.regs[0x10/4])
#define UxSTACLR(U) (U.regs[0x14/4])
#define UxSTASET(U) (U.regs[0x18/4])
#define UxTXREG(U) (U.regs[0x20/4])
#define UxRXREG(U) (U.regs[0x30/4])
#define UxBRG(U) (U.regs[0x40/4])
#define REGS_SPACING (_UART2_BASE_ADDRESS - _UART1_BASE_ADDRESS)
/* PERIPHERAL_CLOCK must be defined in board file */
typedef struct PIC32_UART_tag {
volatile uint32_t *regs;
uint32_t clock;
} PIC32_UART_T;
/* pic uarts are numbered 1 to 6 */
static PIC32_UART_T pic_uart[UART_NUMOF + 1];
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
{
assert(uart <= UART_NUMOF && uart != 0); /*No uart 0 on pic32*/
/* Pin Mux should be setup in board file */
pic_uart[uart].regs =
(volatile uint32_t *)(_UART1_BASE_ADDRESS + (uart - 1) * REGS_SPACING);
pic_uart[uart].clock = PERIPHERAL_CLOCK;
UxBRG(pic_uart[uart])= (pic_uart[uart].clock / (16 * baudrate)) - 1;
UxSTA(pic_uart[uart])= 0;
UxMODE(pic_uart[uart])= _U1MODE_ON_MASK;
UxSTASET(pic_uart[uart])= _U1STA_URXEN_MASK;
UxSTASET(pic_uart[uart])= _U1STA_UTXEN_MASK;
return 0;
}
void uart_write(uart_t uart, const uint8_t *data, size_t len)
{
assert(uart <= UART_NUMOF && uart != 0);
while(len--) {
while(UxSTA(pic_uart[uart])& _U1STA_UTXBF_MASK) {}
UxTXREG(pic_uart[uart]) = *data++;
}
}
void uart_poweron(uart_t uart)
{
assert(uart <= UART_NUMOF && uart != 0);
UxMODESET(pic_uart[uart])= _U1MODE_ON_MASK;
}
void uart_poweroff(uart_t uart)
{
assert(uart <= UART_NUMOF && uart != 0);
UxMODECLR(pic_uart[uart])= _U1MODE_ON_MASK;
}

244
cpu/mips_pic32_common/reset_mod.S

@ -0,0 +1,244 @@
/*
* Copyright 2014-2015, Imagination Technologies Limited and/or its
* affiliated group companies.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
*/
/* ************ PLEASE READ ME !!!! ****************
This file is a copy of the reset_mod.S from $MIPS_ELF_ROOT/share/mips/boot
(from the 2016.05-03 version) with a couple of modifications:
#define SKIP_COPY_TO_RAM - prevents the bootloader copying the whole contents
of flash to ram (as we want to XIP from flash), we copy initialised data from
flash to ram in 'software_init_hook'.
move .org's to before the labels to make the vector labels appear at the vector
addresses.
In boot_debug_exception vector drop out of debug mode before spining, this allows
attachment of an external debug program to investigate a hung system.
Future toolchain versions will have these changes included and this file will
be no longer needed.
Note the above copyright/license is 3 Clause BSD and as such is compatible with LGPLv2.1
as such we grant licensing this file under LGPLv2.1 (See the file LICENSE in the top level
directory for more details) as well.
Thanks for reading.
*/
#define _RESETCODE
.set nomips16
#include <mips/regdef.h>
#include <mips/cpu.h>
#include <mips/asm.h>
.set push
.set nomicromips
LEAF(__reset_vector)
lui a2, %hi(__cpu_init)
addiu a2, %lo(__cpu_init)
mtc0 $0, C0_COUNT # Clear cp0 Count (Used to measure boot time.)
jr a2
.space 32 # Just to cope with a quirk of MIPS malta boards
# this can be deleted for anything else.
END(__reset_vector)
.set pop
LEAF(__cpu_init)
# Verify the code is here due to a reset and not NMI. If this is an NMI then trigger
# a debugger breakpoint using a sdbp instruction.
mfc0 s1, C0_STATUS # Read CP0 Status
ext s1, s1, SR_NMI_SHIFT, 1 # extract NMI
beqz s1, init_resources # /* Branch if this is NOT an NMI exception. */
move k0, t9 # Preserve t9
move k1, a0 # Preserve a0
li $25, 15 # UHI exception operation
li $4, 0 # Use hard register context
sdbbp 1 # Invoke UHI operation
init_resources:
# Init CP0 Status, Count, Compare, Watch*, and Cause.
jal __init_cp0
# Initialise L2/L3 cache
# This could be done from cached code if there is a cca override or similar
# Determine L2/L3 cache config.
lui a2, %hi(__init_l23cache)
addiu a2, a2, %lo(__init_l23cache)
jal a2
init_ic:
# Initialize the L1 instruction cache.
jal __init_icache
# The changing of Kernel mode cacheability must be done from KSEG1
# Since the code is executing from KSEG0 It needs to do a jump to KSEG1 change K0
# and jump back to KSEG0
lui a2, %hi(__change_k0_cca)
addiu a2, a2, %lo(__change_k0_cca)
li a1, 0xf
ins a2, a1, 29, 1 # changed to KSEG1 address by setting bit 29
jalr a2
.weak __init_l23cache_cached
lui a2, %hi(__init_l23cache_cached)
addiu a2, a2, %lo(__init_l23cache_cached)
beqz a2, init_dc
jal a2
init_dc:
# Initialize the L1 data cache
jal __init_dcache
# Initialize the TLB.
jal __init_tlb
# Allow everything else to be initialized via a hook.
.weak __boot_init_hook
lui a2, %hi(__boot_init_hook)
addiu a2, a2, %lo(__boot_init_hook)
beqz a2, 1f
jalr a2
1:
#ifndef SKIP_COPY_TO_RAM
# Copy code and data to RAM
li s1, 0xffffffff
# Copy code and read-only/initialized data from FLASH to (uncached) RAM.
lui a1, %hi(__flash_app_start)
addiu a1, a1, %lo(__flash_app_start)
ins a1, s1, 29, 1 # Make it uncached (kseg1)
lui a2, %hi(__app_start)
addiu a2, a2, %lo(__app_start)
ins a2, s1, 29, 1 # Make it uncached (kseg1)
lui a3, %hi(_edata)
addiu a3, a3, %lo(_edata)
ins a3, s1, 29, 1 # Make it uncached (kseg1)
beq a2, a3, $Lcopy_to_ram_done
$Lnext_ram_word:
lw a0, 0(a1)
sw a0, 0(a2)
addiu a2, a2, 4
addiu a1, a1, 4
bne a3, a2, $Lnext_ram_word
$Lcopy_to_ram_done:
#endif
# Prepare for eret to _start
lui ra, %hi($Lall_done) # If main returns then go to all_done.
addiu ra, ra, %lo($Lall_done)
lui v0, %hi(_start) # Load the address of _start
addiu v0, v0, %lo(_start)
mtc0 v0, C0_ERRPC # Set ErrorEPC to _start
ehb # Clear hazards (makes sure write to ErrorPC has completed)
li a0, 0 # UHI compliant null argument setup
# Return from exception will now execute the application startup code
eret
$Lall_done:
# If _start returns it will return to this point.
# Just spin here reporting the exit.
li $25, 1 # UHI exit operation
move $4, v0 # /* Collect exit code for UHI exit */
sdbbp 1 # Invoke UHI operation
b $Lall_done
END(__cpu_init)
/**************************************************************************************
B O O T E X C E P T I O N H A N D L E R S (CP0 Status[BEV] = 1)
**************************************************************************************/
/* NOTE: the linker script must insure that this code starts at start + 0x200 so the exception */
/* vectors will be addressed properly. All .org assume this! */
/* TLB refill, 32 bit task. */
.org 0x200 # TLB refill, 32 bit task.
LEAF(__boot_tlb_refill)
move k0, t9 # Preserve t9
move k1, a0 # Preserve a0
li $25, 15 # UHI exception operation
li $4, 0 # Use hard register context
sdbbp 1 # Invoke UHI operation
END(__boot_tlb_refill)
.org 0x280 # XTLB refill, 64 bit task. BEV + 0x280
LEAF(__boot_xtlb_refill)
move k0, t9 # Preserve t9
move k1, a0 # Preserve a0
li $25, 15 # UHI exception operation
li $4, 0 # Use hard register context
sdbbp 1 # Invoke UHI operation
END(__boot_xtlb_refill)
.org 0x300 # Cache error exception. BEV + 0x300
LEAF(__boot_cache_error)
move k0, t9 # Preserve t9
move k1, a0 # Preserve a0
li $25, 15 # UHI exception operation
li $4, 0 # Use hard register context
sdbbp 1 # Invoke UHI operation
END(__boot_cache_error)
.org 0x380 # General exception. BEV + 0x380
LEAF(__boot_general_exception)
move k0, t9 # Preserve t9
move k1, a0 # Preserve a0
li $25, 15 # UHI exception operation
li $4, 0 # Use hard register context
sdbbp 1 # Invoke UHI operation
END(__boot_general_exception)
# If you want the above code to fi<