mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2026-01-01 01:41:18 +01:00
Merge pull request #13094 from francois-berder/pic32-uart-3
UART RX implementation on PIC32 devices
This commit is contained in:
commit
934f68ead8
@ -14,5 +14,6 @@ ifeq ($(PROGRAMMER),pic32prog)
|
||||
# * https://docs.creatordev.io/wifire/guides/wifire-programming/
|
||||
# * The triangle `▶` goes into the port number 1 (a hole with a square around it)
|
||||
# opposite side of the JP1 ICSP text.
|
||||
FLASHFILE ?= $(HEXFILE)
|
||||
include $(RIOTMAKE)/tools/pic32prog.inc.mk
|
||||
endif
|
||||
|
||||
@ -15,13 +15,6 @@ extern void dummy(void);
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup pin mux for UART3 this is the one connected
|
||||
* to the mickroBUS
|
||||
*/
|
||||
U3RXR = 0x2; /*connect pin RPF5 to UART3 RX*/
|
||||
RPF4R = 0x1; /*connect pin RPF4 to UART3 TX*/
|
||||
|
||||
/* Turn off all LED's */
|
||||
gpio_init(LED1_PIN, GPIO_OUT);
|
||||
gpio_init(LED2_PIN, GPIO_OUT);
|
||||
@ -34,8 +27,3 @@ void board_init(void)
|
||||
/* 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 */
|
||||
}
|
||||
|
||||
@ -39,18 +39,6 @@ extern "C" {
|
||||
*/
|
||||
#define TICKS_PER_US (48)
|
||||
|
||||
/**
|
||||
* @brief Use the 3rd UART for STDIO on this board
|
||||
*
|
||||
* This is the UART connected to the MikroBus.
|
||||
*/
|
||||
#define STDIO_UART_DEV UART_DEV(3)
|
||||
|
||||
/**
|
||||
* @brief We are using an External Interrupt Controller (all pic32 devices use this mode)
|
||||
*/
|
||||
#define EIC_IRQ (1)
|
||||
|
||||
/**
|
||||
* @name LED pin configuration
|
||||
* @{
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#ifndef PERIPH_CONF_H
|
||||
#define PERIPH_CONF_H
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -45,14 +46,25 @@ extern "C" {
|
||||
|
||||
/**
|
||||
* @name UART Definitions
|
||||
* There are 4 UARTS available on this CPU.
|
||||
* We route debug via UART3 on this board,
|
||||
* this is the UART connected to the MikroBUS
|
||||
*
|
||||
* Note Microchip number the UARTS 1->4
|
||||
* @{
|
||||
*/
|
||||
#define UART_NUMOF (4)
|
||||
static const uart_conf_t uart_config[] = {
|
||||
{ /* UART port available on MikroBus */
|
||||
.base = (volatile unsigned int *)_UART3_BASE_ADDRESS,
|
||||
.clock = PERIPHERAL_CLOCK,
|
||||
.rx_pin = GPIO_PIN(PORT_F, 5),
|
||||
.tx_pin = GPIO_PIN(PORT_F, 4),
|
||||
.rx_mux_reg = &U3RXR,
|
||||
.tx_mux_reg = &RPF4R,
|
||||
.rx_af = GPIO_AF2,
|
||||
.tx_af = GPIO_AF1,
|
||||
.vector = _UART_3_VECTOR,
|
||||
.irq = _UART3_RX_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
#define UART_0_ISR (isr_usart3)
|
||||
#define UART_NUMOF ((unsigned int)ARRAY_SIZE(uart_config))
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -17,6 +17,7 @@ ifeq ($(PROGRAMMER),pic32prog)
|
||||
# * https://docs.creatordev.io/wifire/guides/wifire-programming/
|
||||
# * The triangle `▶` goes into the port number 1 (a hole with a square around it)
|
||||
# opposite side of the JP1 ICSP text.
|
||||
FLASHFILE ?= $(HEXFILE)
|
||||
include $(RIOTMAKE)/tools/pic32prog.inc.mk
|
||||
else ifeq ($(PROGRAMMER),jlink)
|
||||
FLASHFILE ?= $(HEXFILE)
|
||||
|
||||
@ -38,11 +38,6 @@ extern "C" {
|
||||
*/
|
||||
#define TICKS_PER_US (100)
|
||||
|
||||
/**
|
||||
* @brief We are using an External Interrupt Controller (all pic32 devices use this mode)
|
||||
*/
|
||||
#define EIC_IRQ (1)
|
||||
|
||||
/**
|
||||
* @name LED pin configuration
|
||||
* @{
|
||||
@ -79,13 +74,6 @@ extern "C" {
|
||||
*/
|
||||
void board_init(void);
|
||||
|
||||
/**
|
||||
* @brief Use the 4th UART for STDIO on this board
|
||||
*
|
||||
* This is the UART connected to the FTDI USB <-> UART device.
|
||||
*/
|
||||
#define STDIO_UART_DEV UART_DEV(4)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
#ifndef PERIPH_CONF_H
|
||||
#define PERIPH_CONF_H
|
||||
|
||||
#include "cpu.h"
|
||||
#include "periph_cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -42,12 +43,24 @@ extern "C" {
|
||||
|
||||
/**
|
||||
* @name UART Definitions
|
||||
* There are 6 UARTS available on this CPU.
|
||||
*
|
||||
* Note Microchip number the UARTS 1->6.
|
||||
* @{
|
||||
*/
|
||||
#define UART_NUMOF (6)
|
||||
static const uart_conf_t uart_config[] = {
|
||||
{ /* Virtual COM port */
|
||||
.base = (volatile unsigned int *)_UART4_BASE_ADDRESS,
|
||||
.clock = PERIPHERAL_CLOCK,
|
||||
.rx_pin = GPIO_PIN(PORT_F, 2),
|
||||
.tx_pin = GPIO_PIN(PORT_F, 8),
|
||||
.rx_mux_reg = &U4RXR,
|
||||
.tx_mux_reg = &RPF8R,
|
||||
.rx_af = GPIO_AF11,
|
||||
.tx_af = GPIO_AF2,
|
||||
.vector = _UART4_RX_VECTOR,
|
||||
},
|
||||
};
|
||||
|
||||
#define UART_0_ISR (isr_usart4)
|
||||
#define UART_NUMOF ((unsigned int)ARRAY_SIZE(uart_config))
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -19,13 +19,6 @@ extern void dummy(void);
|
||||
|
||||
void board_init(void)
|
||||
{
|
||||
/*
|
||||
* Setup pin mux for UART4 this is the one connected
|
||||
* to the ftdi chip (usb<->uart)
|
||||
*/
|
||||
U4RXR = 0xb; /* connect pin RPF2 to UART 4 RX */
|
||||
RPF8R = 0x2; /* connect pin RPF8 to UART 4 TX */
|
||||
|
||||
/* Turn off all LED's */
|
||||
gpio_init(LED1_PIN, GPIO_OUT);
|
||||
gpio_init(LED2_PIN, GPIO_OUT);
|
||||
@ -42,8 +35,3 @@ void board_init(void)
|
||||
/* 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 */
|
||||
}
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cpu_conf.h"
|
||||
#include "thread.h"
|
||||
#include "irq.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -46,6 +47,18 @@ static inline void cpu_print_last_instruction(void)
|
||||
*/
|
||||
void cpu_init(void);
|
||||
|
||||
/**
|
||||
* @brief Trigger a conditional context scheduler run / context switch
|
||||
*
|
||||
* This function is supposed to be called in the end of each ISR.
|
||||
*/
|
||||
static inline void mips32r2_isr_end(void)
|
||||
{
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield_higher();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
72
cpu/mips32r2_common/include/eic.h
Normal file
72
cpu/mips32r2_common/include/eic.h
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu
|
||||
* @brief Imagination Technologies MIPS32R2 Common implementation
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief API for supporting External Interrupt Controllers (EIC mode)
|
||||
*
|
||||
* @author Neil Jones <neil.jones@imgtec.com>
|
||||
*/
|
||||
|
||||
#ifndef EIC_H
|
||||
#define EIC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief External ISR callback
|
||||
*/
|
||||
typedef void (*external_isr_ptr_t)(void);
|
||||
|
||||
/**
|
||||
* @brief Set External ISR callback
|
||||
*/
|
||||
void set_external_isr_cb(int vecNum, external_isr_ptr_t cbFunc);
|
||||
|
||||
/**
|
||||
* @brief Configure interrupt priority
|
||||
*
|
||||
* @param[in] vecNum
|
||||
* @param[in] priority
|
||||
* @param[in] subpriority
|
||||
*/
|
||||
void eic_configure_priority(int vecNum, int priority, int subpriority);
|
||||
|
||||
/**
|
||||
* @brief Enable interrupt
|
||||
*
|
||||
* @param[in] vecNum
|
||||
*/
|
||||
void eic_enable(int vecNum);
|
||||
|
||||
/**
|
||||
* @brief Disable interrupt
|
||||
*
|
||||
* @param[in] vecNum
|
||||
*/
|
||||
void eic_disable(int vecNum);
|
||||
|
||||
/**
|
||||
* @brief Clear interrupt flag
|
||||
*
|
||||
* @param[in] vecNum
|
||||
*/
|
||||
void eic_clear_flag(int vecNum);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EIC_H */
|
||||
/** @} */
|
||||
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_mips32r2_common
|
||||
* @brief Imagination Technologies MIPS32R2 Common implementation
|
||||
* @{
|
||||
*
|
||||
* @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 /* EIC_IRQ_H */
|
||||
/** @} */
|
||||
100
cpu/mips32r2_common/mips_excpt_isr.S
Normal file
100
cpu/mips32r2_common/mips_excpt_isr.S
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#
|
||||
# Keep each function in a separate named section
|
||||
#define _FUNCTION_SECTIONS_
|
||||
.set nomips16
|
||||
|
||||
#include <mips/regdef.h>
|
||||
#include <mips/asm.h>
|
||||
#include <mips/cpu.h>
|
||||
|
||||
#define VEC_SPACE (SZPTR * 8)
|
||||
|
||||
LEAF(__isr_vec)
|
||||
.set push
|
||||
.set noat
|
||||
AENT(__isr_vec_sw0)
|
||||
.weak _mips_isr_sw0
|
||||
LA k1, _mips_isr_sw0
|
||||
beqz k1, 1f
|
||||
jr k1
|
||||
.org VEC_SPACE
|
||||
AENT(__isr_vec_sw1)
|
||||
.weak _mips_isr_sw1
|
||||
LA k1, _mips_isr_sw1
|
||||
beqz k1, 1f
|
||||
jr k1
|
||||
.org 2 * VEC_SPACE
|
||||
AENT(__isr_vec_hw0)
|
||||
.weak _mips_isr_hw0
|
||||
LA k1, _mips_isr_hw0
|
||||
beqz k1, 1f
|
||||
jr k1
|
||||
.org 3 * VEC_SPACE
|
||||
AENT(__isr_vec_hw1)
|
||||
.weak _mips_isr_hw1
|
||||
LA k1, _mips_isr_hw1
|
||||
beqz k1, 1f
|
||||
jr k1
|
||||
.org 4 * VEC_SPACE
|
||||
AENT(__isr_vec_hw2)
|
||||
.weak _mips_isr_hw2
|
||||
LA k1, _mips_isr_hw2
|
||||
beqz k1, 1f
|
||||
jr k1
|
||||
.org 5 * VEC_SPACE
|
||||
AENT(__isr_vec_hw3)
|
||||
.weak _mips_isr_hw3
|
||||
LA k1, _mips_isr_hw3
|
||||
beqz k1, 1f
|
||||
jr k1
|
||||
.org 6 * VEC_SPACE
|
||||
AENT(__isr_vec_hw4)
|
||||
.weak _mips_isr_hw4
|
||||
LA k1, _mips_isr_hw4
|
||||
beqz k1, 1f
|
||||
jr k1
|
||||
.org 7 * VEC_SPACE
|
||||
AENT(__isr_vec_hw5)
|
||||
.weak _mips_isr_hw5
|
||||
LA k1, _mips_isr_hw5
|
||||
beqz k1, 1f
|
||||
jr k1
|
||||
.org 8 * VEC_SPACE
|
||||
AENT(__isr_vec_fallback)
|
||||
.weak _mips_interrupt
|
||||
1:
|
||||
LA k1, _mips_interrupt
|
||||
beqz k1, 1b
|
||||
jr k1
|
||||
.set pop
|
||||
END(__isr_vec)
|
||||
@ -233,10 +233,15 @@ _mips_handle_exception(struct gpctx *ctx, int exception)
|
||||
irq_restore(status);
|
||||
return;
|
||||
}
|
||||
else if (ctx->t2[1] == __MIPS_UHI_READ && ctx->a[0] == STDIN_FILENO) {
|
||||
ctx->v[0] = stdio_read((void *)ctx->a[1], ctx->a[2]);
|
||||
ctx->epc += 4; /* move PC past the syscall */
|
||||
return;
|
||||
}
|
||||
else if (ctx->t2[1] == __MIPS_UHI_FSTAT &&
|
||||
(ctx->a[0] == STDOUT_FILENO || ctx->a[0] == STDERR_FILENO)) {
|
||||
(ctx->a[0] == STDOUT_FILENO || ctx->a[0] == STDIN_FILENO || ctx->a[0] == STDERR_FILENO)) {
|
||||
/*
|
||||
* Printf fstat's the stdout/stderr file so
|
||||
* Printf fstat's the stdout/stdin/stderr file so
|
||||
* fill out a minimal struct stat.
|
||||
*/
|
||||
struct stat *sbuf = (struct stat *)ctx->a[1];
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
USEMODULE += mips_pic32_common
|
||||
USEMODULE += mips_pic32_common_periph
|
||||
|
||||
# mips32 needs periph_timer for its gettimeofday() implementation
|
||||
USEMODULE += periph_timer
|
||||
|
||||
include $(RIOTCPU)/mips32r2_common/Makefile.dep
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
include $(RIOTCPU)/mips32r2_common/Makefile.include
|
||||
|
||||
CFLAGS += -DCPU_FAM_$(call uppercase_and_underscore,$(CPU_FAM))
|
||||
|
||||
INCLUDES += -I$(RIOTCPU)/mips_pic32_common/include
|
||||
|
||||
95
cpu/mips_pic32_common/eic.c
Normal file
95
cpu/mips_pic32_common/eic.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Francois Berder
|
||||
*
|
||||
* 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 "cpu_conf.h"
|
||||
#include "eic.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(CPU_FAM_PIC32MX)
|
||||
#define VEC_NUMOF (64)
|
||||
#elif defined (CPU_FAM_PIC32MZ)
|
||||
#define VEC_NUMOF (256)
|
||||
#endif
|
||||
|
||||
#define IECSET(V) *(volatile uint32_t *)((uintptr_t)&IEC0SET + 0x10 * ((V) / 32))
|
||||
#define IECCLR(V) *(volatile uint32_t *)((uintptr_t)&IEC0CLR + 0x10 * ((V) / 32))
|
||||
#define IFSCLR(V) *(volatile uint32_t *)((uintptr_t)&IFS0CLR + 0x10 * ((V) / 32))
|
||||
#define IPC(V) *(volatile uint32_t *)((uintptr_t)&IPC0 + 0x10 * ((V) / 4))
|
||||
|
||||
static external_isr_ptr_t vectors[VEC_NUMOF];
|
||||
|
||||
void set_external_isr_cb(int vecNum, external_isr_ptr_t cbFunc)
|
||||
{
|
||||
if (vecNum < VEC_NUMOF)
|
||||
vectors[vecNum] = cbFunc;
|
||||
}
|
||||
|
||||
/* note Compiler inserts GP context save + restore code (to current stack). */
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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) that's 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)
|
||||
{
|
||||
#if defined(CPU_FAM_PIC32MX)
|
||||
int vecNum = INTSTAT & _INTSTAT_VEC_MASK;
|
||||
#elif defined (CPU_FAM_PIC32MZ)
|
||||
int vecNum = INTSTAT & _INTSTAT_SIRQ_MASK;
|
||||
#endif
|
||||
|
||||
if (vectors[vecNum])
|
||||
vectors[vecNum]();
|
||||
}
|
||||
|
||||
void eic_configure_priority(int vecNum, int priority, int subpriority)
|
||||
{
|
||||
unsigned int offset;
|
||||
|
||||
if (vecNum >= VEC_NUMOF)
|
||||
return;
|
||||
|
||||
offset = 8 * (vecNum & 0x3);
|
||||
IPC(vecNum) &= ~(0x1F << offset);
|
||||
IPC(vecNum) |= ((priority << 2) | (subpriority)) << offset;
|
||||
}
|
||||
|
||||
void eic_enable(int vecNum)
|
||||
{
|
||||
if (vecNum >= VEC_NUMOF)
|
||||
return;
|
||||
|
||||
IECSET(vecNum) = 1U << (vecNum & 0x1F);
|
||||
}
|
||||
|
||||
void eic_disable(int vecNum)
|
||||
{
|
||||
if (vecNum >= VEC_NUMOF)
|
||||
return;
|
||||
|
||||
IECCLR(vecNum) = 1U << (vecNum & 0x1F);
|
||||
}
|
||||
|
||||
void eic_clear_flag(int vecNum)
|
||||
{
|
||||
if (vecNum >= VEC_NUMOF)
|
||||
return;
|
||||
|
||||
IFSCLR(vecNum) = 1U << (vecNum & 0x1F);
|
||||
}
|
||||
@ -78,6 +78,47 @@ enum {
|
||||
*/
|
||||
#define PERIPH_TIMER_PROVIDES_SET
|
||||
|
||||
|
||||
/**
|
||||
* @brief Available MUX values for configuring a pin's alternate function
|
||||
*/
|
||||
typedef enum {
|
||||
GPIO_AF0 = 0, /**< use alternate function 0 */
|
||||
GPIO_AF1, /**< use alternate function 1 */
|
||||
GPIO_AF2, /**< use alternate function 2 */
|
||||
GPIO_AF3, /**< use alternate function 3 */
|
||||
GPIO_AF4, /**< use alternate function 4 */
|
||||
GPIO_AF5, /**< use alternate function 5 */
|
||||
GPIO_AF6, /**< use alternate function 6 */
|
||||
GPIO_AF7, /**< use alternate function 7 */
|
||||
GPIO_AF8, /**< use alternate function 8 */
|
||||
GPIO_AF9, /**< use alternate function 9 */
|
||||
GPIO_AF10, /**< use alternate function 10 */
|
||||
GPIO_AF11, /**< use alternate function 11 */
|
||||
GPIO_AF12, /**< use alternate function 12 */
|
||||
GPIO_AF13, /**< use alternate function 13 */
|
||||
GPIO_AF14, /**< use alternate function 14 */
|
||||
GPIO_AF15 /**< use alternate function 15 */
|
||||
} gpio_af_t;
|
||||
|
||||
/**
|
||||
* @brief Structure for UART configuration data
|
||||
*/
|
||||
typedef struct {
|
||||
volatile unsigned int * base; /**< UART device base register address */
|
||||
uint32_t clock; /**< Peripheral clock frequency */
|
||||
gpio_t rx_pin; /**< RX pin */
|
||||
gpio_t tx_pin; /**< TX pin */
|
||||
volatile unsigned int *rx_mux_reg; /**< Address of RX mux register*/
|
||||
volatile unsigned int *tx_mux_reg; /**< Address of TX mux register */
|
||||
gpio_af_t rx_af; /**< alternate function for RX pin */
|
||||
gpio_af_t tx_af; /**< alternate function for TX pin */
|
||||
uint32_t vector; /**< vector number */
|
||||
#ifdef CPU_FAM_PIC32MX
|
||||
uint32_t irq; /**< interrupt number */
|
||||
#endif
|
||||
} uart_conf_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
38
cpu/mips_pic32_common/periph/pm.c
Normal file
38
cpu/mips_pic32_common/periph/pm.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2020 Francois Berder
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup cpu_mips_pic32_common
|
||||
* @ingroup drivers_periph_pm
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief common periph/pm functions
|
||||
*
|
||||
* @author Francois Berder <fberder@outlook.fr >
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "periph/pm.h"
|
||||
|
||||
void pm_reboot(void)
|
||||
{
|
||||
/* Unlock OSCCON */
|
||||
SYSKEY = 0x00000000;
|
||||
SYSKEY = 0xAA996655;
|
||||
SYSKEY = 0x556699AA;
|
||||
|
||||
/* Set SWRST bit to arm reset */
|
||||
RSWRSTSET = 1;
|
||||
|
||||
/* Read RSWRST register to trigger reset */
|
||||
RSWRST;
|
||||
|
||||
while(1);
|
||||
}
|
||||
@ -34,9 +34,7 @@
|
||||
#include "div.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef EIC_IRQ
|
||||
#include "eic_irq.h"
|
||||
#endif
|
||||
#include "eic.h"
|
||||
|
||||
/*
|
||||
* setting TIMER_ACCURACY_SHIFT lower will improve accuracy
|
||||
@ -70,7 +68,39 @@
|
||||
static timer_isr_ctx_t timer_isr_ctx;
|
||||
volatile unsigned int counter;
|
||||
volatile unsigned int compares[CHANNELS];
|
||||
static volatile int spurious_int;
|
||||
|
||||
static void timer_isr(void)
|
||||
{
|
||||
IFS0CLR =_IFS0_CTIF_MASK;
|
||||
|
||||
uint32_t status = irq_disable();
|
||||
counter += TIMER_ACCURACY;
|
||||
irq_restore(status);
|
||||
|
||||
if (counter == compares[0]) {
|
||||
/*
|
||||
* The Xtimer code expects the ISR to take some time
|
||||
* but our counter is a fake software one, so bump it a
|
||||
* bit to give the impression some time elapsed in the ISR.
|
||||
* Without this the callback ( _shoot(timer) on xtimer_core.c )
|
||||
* never fires.
|
||||
*/
|
||||
counter += TIMER_ACCURACY;
|
||||
timer_isr_ctx.cb(timer_isr_ctx.arg, 0);
|
||||
mips32r2_isr_end();
|
||||
}
|
||||
if (counter == compares[1]) {
|
||||
timer_isr_ctx.cb(timer_isr_ctx.arg, 1);
|
||||
mips32r2_isr_end();
|
||||
}
|
||||
if (counter == compares[2]) {
|
||||
timer_isr_ctx.cb(timer_isr_ctx.arg, 2);
|
||||
mips32r2_isr_end();
|
||||
}
|
||||
|
||||
mips_setcompare(mips_getcount() + TICKS_PER_US * TIMER_ACCURACY);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The mips toolchain C library does not implement gettimeofday()
|
||||
@ -111,12 +141,9 @@ 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
|
||||
|
||||
set_external_isr_cb(_CORE_TIMER_VECTOR, timer_isr);
|
||||
eic_configure_priority(_CORE_TIMER_VECTOR, 1, 0);
|
||||
eic_enable(_CORE_TIMER_VECTOR);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -189,95 +216,3 @@ void timer_stop(tim_t dev)
|
||||
(void)dev;
|
||||
mips32_bs_c0(C0_CAUSE, CR_DC);
|
||||
}
|
||||
|
||||
void timer_irq_enable(tim_t dev)
|
||||
{
|
||||
(void)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)
|
||||
{
|
||||
(void)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) that's 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_disable();
|
||||
counter += TIMER_ACCURACY;
|
||||
irq_restore(status);
|
||||
|
||||
if (counter == compares[0]) {
|
||||
/*
|
||||
* The Xtimer code expects the ISR to take some time
|
||||
* but our counter is a fake software one, so bump it a
|
||||
* bit to give the impression some time elapsed in the ISR.
|
||||
* Without this the callback ( _shoot(timer) on xtimer_core.c )
|
||||
* never fires.
|
||||
*/
|
||||
counter += TIMER_ACCURACY;
|
||||
timer_isr_ctx.cb(timer_isr_ctx.arg, 0);
|
||||
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
if (counter == compares[1]) {
|
||||
timer_isr_ctx.cb(timer_isr_ctx.arg, 1);
|
||||
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
if (counter == compares[2]) {
|
||||
timer_isr_ctx.cb(timer_isr_ctx.arg, 2);
|
||||
|
||||
if (sched_context_switch_request) {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
|
||||
mips_setcompare(mips_getcount() + TICKS_PER_US * TIMER_ACCURACY);
|
||||
|
||||
}
|
||||
else {
|
||||
spurious_int++;
|
||||
}
|
||||
}
|
||||
@ -18,74 +18,176 @@
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
#include <assert.h>
|
||||
|
||||
#include "cpu.h"
|
||||
#include "eic.h"
|
||||
#include "sched.h"
|
||||
#include "thread.h"
|
||||
#include "assert.h"
|
||||
#include "periph/uart.h"
|
||||
#include "board.h"
|
||||
#include "periph/gpio.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)
|
||||
#define UxMODE(U) ((U)[0x00/4])
|
||||
#define UxMODECLR(U) ((U)[0x04/4])
|
||||
#define UxMODESET(U) ((U)[0x08/4])
|
||||
#define UxSTA(U) ((U)[0x10/4])
|
||||
#define UxSTACLR(U) ((U)[0x14/4])
|
||||
#define UxSTASET(U) ((U)[0x18/4])
|
||||
#define UxTXREG(U) ((U)[0x20/4])
|
||||
#define UxRXREG(U) ((U)[0x30/4])
|
||||
#define UxBRG(U) ((U)[0x40/4])
|
||||
|
||||
/* PERIPHERAL_CLOCK must be defined in board file */
|
||||
/**
|
||||
* @brief Allocate memory to store the callback functions.
|
||||
*/
|
||||
static uart_isr_ctx_t uart_ctx[UART_NUMOF];
|
||||
|
||||
typedef struct PIC32_UART_tag {
|
||||
volatile uint32_t *regs;
|
||||
uint32_t clock;
|
||||
} PIC32_UART_T;
|
||||
static void irq_handler(uart_t uart)
|
||||
{
|
||||
uint32_t status = UxSTA(uart_config[uart].base);
|
||||
|
||||
/* pic uarts are numbered 1 to 6 */
|
||||
static PIC32_UART_T pic_uart[UART_NUMOF + 1];
|
||||
if (status & _U1STA_URXDA_MASK) {
|
||||
uart_ctx[uart].rx_cb(uart_ctx[uart].arg, UxRXREG(uart_config[uart].base));
|
||||
}
|
||||
if (status & _U1STA_OERR_MASK) {
|
||||
UxSTA(uart_config[uart].base) &= ~_U1STA_OERR_MASK;
|
||||
}
|
||||
#ifdef CPU_FAM_PIC32MX
|
||||
eic_clear_flag(uart_config[uart].irq);
|
||||
#else
|
||||
eic_clear_flag(uart_config[uart].vector);
|
||||
#endif
|
||||
|
||||
mips32r2_isr_end();
|
||||
}
|
||||
|
||||
#ifdef UART_0_ISR
|
||||
void UART_0_ISR(void)
|
||||
{
|
||||
irq_handler(UART_DEV(0));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UART_1_ISR
|
||||
void UART_1_ISR(void)
|
||||
{
|
||||
irq_handler(UART_DEV(1));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UART_2_ISR
|
||||
void UART_2_ISR(void)
|
||||
{
|
||||
irq_handler(UART_DEV(2));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UART_3_ISR
|
||||
void UART_3_ISR(void)
|
||||
{
|
||||
irq_handler(UART_DEV(3));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UART_4_ISR
|
||||
void UART_4_ISR(void)
|
||||
{
|
||||
irq_handler(UART_DEV(4));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UART_5_ISR
|
||||
void UART_5_ISR(void)
|
||||
{
|
||||
irq_handler(UART_DEV(5));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void uart_init_pins(uart_t uart, uart_rx_cb_t rx_cb)
|
||||
{
|
||||
/* configure TX pin */
|
||||
gpio_init(uart_config[uart].tx_pin, GPIO_OUT);
|
||||
/* set TX pin high to avoid garbage during further initialization */
|
||||
gpio_set(uart_config[uart].tx_pin);
|
||||
*(uart_config[uart].tx_mux_reg) = uart_config[uart].tx_af;
|
||||
|
||||
/* configure RX pin */
|
||||
if (rx_cb) {
|
||||
gpio_init(uart_config[uart].rx_pin, GPIO_IN_PU);
|
||||
*(uart_config[uart].rx_mux_reg) = uart_config[uart].rx_af;
|
||||
}
|
||||
}
|
||||
|
||||
int uart_init(uart_t uart, uint32_t baudrate, uart_rx_cb_t rx_cb, void *arg)
|
||||
{
|
||||
(void)rx_cb;
|
||||
(void)arg;
|
||||
assert(uart < UART_NUMOF);
|
||||
|
||||
assert(uart <= UART_NUMOF && uart != 0); /*No uart 0 on pic32*/
|
||||
uart_init_pins(uart, rx_cb);
|
||||
|
||||
/* Pin Mux should be setup in board file */
|
||||
UxBRG(uart_config[uart].base) = (uart_config[uart].clock / (16 * baudrate)) - 1;
|
||||
UxSTA(uart_config[uart].base) = 0;
|
||||
if (rx_cb) {
|
||||
/* register callbacks */
|
||||
uart_ctx[uart].rx_cb = rx_cb;
|
||||
uart_ctx[uart].arg = arg;
|
||||
UxSTASET(uart_config[uart].base) = _U1STA_URXEN_MASK;
|
||||
|
||||
pic_uart[uart].regs =
|
||||
(volatile uint32_t *)(_UART1_BASE_ADDRESS + (uart - 1) * REGS_SPACING);
|
||||
pic_uart[uart].clock = PERIPHERAL_CLOCK;
|
||||
switch (uart) {
|
||||
#ifdef UART_0_ISR
|
||||
case UART_DEV(0): set_external_isr_cb(uart_config[uart].vector, UART_0_ISR); break;
|
||||
#endif
|
||||
#ifdef UART_1_ISR
|
||||
case UART_DEV(1): set_external_isr_cb(uart_config[uart].vector, UART_1_ISR); break;
|
||||
#endif
|
||||
#ifdef UART_2_ISR
|
||||
case UART_DEV(2): set_external_isr_cb(uart_config[uart].vector, UART_2_ISR); break;
|
||||
#endif
|
||||
#ifdef UART_3_ISR
|
||||
case UART_DEV(3): set_external_isr_cb(uart_config[uart].vector, UART_3_ISR); break;
|
||||
#endif
|
||||
#ifdef UART_4_ISR
|
||||
case UART_DEV(4): set_external_isr_cb(uart_config[uart].vector, UART_4_ISR); break;
|
||||
#endif
|
||||
#ifdef UART_5_ISR
|
||||
case UART_DEV(5): set_external_isr_cb(uart_config[uart].vector, UART_5_ISR); break;
|
||||
#endif
|
||||
}
|
||||
eic_configure_priority(uart_config[uart].vector, 1, 0);
|
||||
|
||||
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;
|
||||
#ifdef CPU_FAM_PIC32MX
|
||||
eic_enable(uart_config[uart].irq);
|
||||
#else
|
||||
eic_enable(uart_config[uart].vector);
|
||||
#endif
|
||||
|
||||
}
|
||||
UxSTASET(uart_config[uart].base) = _U1STA_UTXEN_MASK;
|
||||
UxMODE(uart_config[uart].base) = _U1MODE_ON_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void uart_write(uart_t uart, const uint8_t *data, size_t len)
|
||||
{
|
||||
assert(uart <= UART_NUMOF && uart != 0);
|
||||
assert(uart < UART_NUMOF);
|
||||
|
||||
while(len--) {
|
||||
while(UxSTA(pic_uart[uart])& _U1STA_UTXBF_MASK) {}
|
||||
UxTXREG(pic_uart[uart]) = *data++;
|
||||
while(UxSTA(uart_config[uart].base)& _U1STA_UTXBF_MASK) {}
|
||||
UxTXREG(uart_config[uart].base) = *data++;
|
||||
}
|
||||
}
|
||||
|
||||
void uart_poweron(uart_t uart)
|
||||
{
|
||||
assert(uart <= UART_NUMOF && uart != 0);
|
||||
assert(uart < UART_NUMOF);
|
||||
|
||||
UxMODESET(pic_uart[uart])= _U1MODE_ON_MASK;
|
||||
UxMODESET(uart_config[uart].base)= _U1MODE_ON_MASK;
|
||||
|
||||
}
|
||||
|
||||
void uart_poweroff(uart_t uart)
|
||||
{
|
||||
assert(uart <= UART_NUMOF && uart != 0);
|
||||
assert(uart < UART_NUMOF);
|
||||
|
||||
UxMODECLR(pic_uart[uart])= _U1MODE_ON_MASK;
|
||||
UxMODECLR(uart_config[uart].base)= _U1MODE_ON_MASK;
|
||||
}
|
||||
|
||||
@ -1 +1,4 @@
|
||||
CPU_ARCH = m4k
|
||||
CPU_FAM = pic32mx
|
||||
|
||||
-include $(RIOTCPU)/mips_pic32_common/Makefile.features
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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 "board.h"
|
||||
#include "eic_irq.h"
|
||||
|
||||
void eic_irq_configure(int irq_num)
|
||||
{
|
||||
(void)irq_num;
|
||||
/* Only timer interrupt supported currently */
|
||||
assert(irq_num == EIC_IRQ_TIMER);
|
||||
|
||||
/* Enable IRQ0 CPU Timer Interrupt */
|
||||
IEC0SET = _IEC0_CTIE_MASK;
|
||||
|
||||
/* Set IRQ 0 to priority 1.0 */
|
||||
IPC0SET = 1 << _IPC0_CTIP_POSITION | 0 << _IPC0_CTIS_POSITION;
|
||||
}
|
||||
|
||||
void eic_irq_enable(int irq_num)
|
||||
{
|
||||
(void)irq_num;
|
||||
/* Only timer interrupt supported currently */
|
||||
assert(irq_num == EIC_IRQ_TIMER);
|
||||
|
||||
/* Enable IRQ0 CPU Timer Interrupt */
|
||||
IEC0SET = _IEC0_CTIE_MASK;
|
||||
}
|
||||
|
||||
void eic_irq_disable(int irq_num)
|
||||
{
|
||||
(void)irq_num;
|
||||
/* Only timer interrupt supported currently */
|
||||
assert(irq_num == EIC_IRQ_TIMER);
|
||||
|
||||
/* Disable IRQ0 CPU Timer Interrupt */
|
||||
IEC0CLR = _IEC0_CTIE_MASK;
|
||||
}
|
||||
|
||||
void eic_irq_ack(int irq_num)
|
||||
{
|
||||
(void)irq_num;
|
||||
/* Only timer interrupt supported currently */
|
||||
assert(irq_num == EIC_IRQ_TIMER);
|
||||
|
||||
/* Ack the timer interrupt */
|
||||
IFS0CLR =_IFS0_CTIF_MASK;
|
||||
}
|
||||
@ -1,3 +1,6 @@
|
||||
CPU_ARCH = m5101
|
||||
CPU_FAM = pic32mz
|
||||
|
||||
FEATURES_PROVIDED += periph_hwrng
|
||||
|
||||
-include $(RIOTCPU)/mips_pic32_common/Makefile.features
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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 "board.h"
|
||||
#include "eic_irq.h"
|
||||
|
||||
void eic_irq_configure(int irq_num)
|
||||
{
|
||||
(void)irq_num;
|
||||
/* Only timer interrupt supported currently */
|
||||
assert(irq_num == EIC_IRQ_TIMER);
|
||||
|
||||
/* Enable IRQ0 CPU Timer Interrupt */
|
||||
IEC0SET = _IEC0_CTIE_MASK;
|
||||
|
||||
/* Set IRQ 0 to priority 1.0 */
|
||||
IPC0SET = 1 << _IPC0_CTIP_POSITION | 0 << _IPC0_CTIS_POSITION;
|
||||
}
|
||||
|
||||
void eic_irq_enable(int irq_num)
|
||||
{
|
||||
(void)irq_num;
|
||||
/* Only timer interrupt supported currently */
|
||||
assert(irq_num == EIC_IRQ_TIMER);
|
||||
|
||||
/* Enable IRQ0 CPU Timer Interrupt */
|
||||
IEC0SET = _IEC0_CTIE_MASK;
|
||||
}
|
||||
|
||||
void eic_irq_disable(int irq_num)
|
||||
{
|
||||
(void)irq_num;
|
||||
/* Only timer interrupt supported currently */
|
||||
assert(irq_num == EIC_IRQ_TIMER);
|
||||
|
||||
/* Disable IRQ0 CPU Timer Interrupt */
|
||||
IEC0CLR = _IEC0_CTIE_MASK;
|
||||
}
|
||||
|
||||
void eic_irq_ack(int irq_num)
|
||||
{
|
||||
(void)irq_num;
|
||||
/* Only timer interrupt supported currently */
|
||||
assert(irq_num == EIC_IRQ_TIMER);
|
||||
|
||||
/* Ack the timer interrupt */
|
||||
IFS0CLR =_IFS0_CTIF_MASK;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user