mirror of https://github.com/ARMmbed/mbed-os.git
Merge remote-tracking branch 'upstream/master'
commit
c16a115e18
|
@ -368,23 +368,46 @@ typedef struct { /*!< (@ 0x40028000) WKT Structure
|
||||||
} LPC_WKT_TypeDef;
|
} LPC_WKT_TypeDef;
|
||||||
/*@}*/ /* end of group LPC8xx_WKT */
|
/*@}*/ /* end of group LPC8xx_WKT */
|
||||||
|
|
||||||
|
|
||||||
/*------------- Multi-Rate Timer(MRT) --------------------------------------------------*/
|
/*------------- Multi-Rate Timer(MRT) --------------------------------------------------*/
|
||||||
typedef struct {
|
//New, Copied from lpc824
|
||||||
__IO uint32_t INTVAL;
|
/**
|
||||||
__IO uint32_t TIMER;
|
* @brief Multi-Rate Timer (MRT) (MRT)
|
||||||
__IO uint32_t CTRL;
|
*/
|
||||||
__IO uint32_t STAT;
|
typedef struct { /*!< (@ 0x40004000) MRT Structure */
|
||||||
} MRT_Channel_cfg_Type;
|
__IO uint32_t INTVAL0; /*!< (@ 0x40004000) MRT0 Time interval value register. This value
|
||||||
|
is loaded into the TIMER0 register. */
|
||||||
typedef struct {
|
__I uint32_t TIMER0; /*!< (@ 0x40004004) MRT0 Timer register. This register reads the
|
||||||
MRT_Channel_cfg_Type Channel[4];
|
value of the down-counter. */
|
||||||
uint32_t Reserved0[1];
|
__IO uint32_t CTRL0; /*!< (@ 0x40004008) MRT0 Control register. This register controls
|
||||||
__IO uint32_t IDLE_CH;
|
the MRT0 modes. */
|
||||||
__IO uint32_t IRQ_FLAG;
|
__IO uint32_t STAT0; /*!< (@ 0x4000400C) MRT0 Status register. */
|
||||||
|
__IO uint32_t INTVAL1; /*!< (@ 0x40004010) MRT0 Time interval value register. This value
|
||||||
|
is loaded into the TIMER0 register. */
|
||||||
|
__I uint32_t TIMER1; /*!< (@ 0x40004014) MRT0 Timer register. This register reads the
|
||||||
|
value of the down-counter. */
|
||||||
|
__IO uint32_t CTRL1; /*!< (@ 0x40004018) MRT0 Control register. This register controls
|
||||||
|
the MRT0 modes. */
|
||||||
|
__IO uint32_t STAT1; /*!< (@ 0x4000401C) MRT0 Status register. */
|
||||||
|
__IO uint32_t INTVAL2; /*!< (@ 0x40004020) MRT0 Time interval value register. This value
|
||||||
|
is loaded into the TIMER0 register. */
|
||||||
|
__I uint32_t TIMER2; /*!< (@ 0x40004024) MRT0 Timer register. This register reads the
|
||||||
|
value of the down-counter. */
|
||||||
|
__IO uint32_t CTRL2; /*!< (@ 0x40004028) MRT0 Control register. This register controls
|
||||||
|
the MRT0 modes. */
|
||||||
|
__IO uint32_t STAT2; /*!< (@ 0x4000402C) MRT0 Status register. */
|
||||||
|
__IO uint32_t INTVAL3; /*!< (@ 0x40004030) MRT0 Time interval value register. This value
|
||||||
|
is loaded into the TIMER0 register. */
|
||||||
|
__I uint32_t TIMER3; /*!< (@ 0x40004034) MRT0 Timer register. This register reads the
|
||||||
|
value of the down-counter. */
|
||||||
|
__IO uint32_t CTRL3; /*!< (@ 0x40004038) MRT0 Control register. This register controls
|
||||||
|
the MRT0 modes. */
|
||||||
|
__IO uint32_t STAT3; /*!< (@ 0x4000403C) MRT0 Status register. */
|
||||||
|
__I uint32_t RESERVED0[45];
|
||||||
|
__I uint32_t IDLE_CH; /*!< (@ 0x400040F4) Idle channel register. This register returns
|
||||||
|
the number of the first idle channel. */
|
||||||
|
__IO uint32_t IRQ_FLAG; /*!< (@ 0x400040F8) Global interrupt flag register */
|
||||||
} LPC_MRT_TypeDef;
|
} LPC_MRT_TypeDef;
|
||||||
|
|
||||||
|
|
||||||
/*------------- Universal Asynchronous Receiver Transmitter (USART) -----------*/
|
/*------------- Universal Asynchronous Receiver Transmitter (USART) -----------*/
|
||||||
/** @addtogroup LPC8xx_UART LPC8xx Universal Asynchronous Receiver/Transmitter
|
/** @addtogroup LPC8xx_UART LPC8xx Universal Asynchronous Receiver/Transmitter
|
||||||
@{
|
@{
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
#define DEVICE_SERIAL_FC 1
|
#define DEVICE_SERIAL_FC 1
|
||||||
|
|
||||||
#define DEVICE_I2C 1
|
#define DEVICE_I2C 1
|
||||||
#define DEVICE_I2CSLAVE 0
|
#define DEVICE_I2CSLAVE 1
|
||||||
|
|
||||||
#define DEVICE_SPI 1
|
#define DEVICE_SPI 1
|
||||||
#define DEVICE_SPISLAVE 1
|
#define DEVICE_SPISLAVE 1
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
#define DEVICE_ETHERNET 0
|
#define DEVICE_ETHERNET 0
|
||||||
|
|
||||||
#define DEVICE_PWMOUT 0
|
#define DEVICE_PWMOUT 1
|
||||||
|
|
||||||
#define DEVICE_SEMIHOST 0
|
#define DEVICE_SEMIHOST 0
|
||||||
#define DEVICE_LOCALFILESYSTEM 0
|
#define DEVICE_LOCALFILESYSTEM 0
|
||||||
|
|
|
@ -43,6 +43,11 @@ struct spi_s {
|
||||||
unsigned char spi_n;
|
unsigned char spi_n;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct pwmout_s {
|
||||||
|
LPC_SCT_TypeDef* pwm;
|
||||||
|
uint32_t pwm_ch;
|
||||||
|
};
|
||||||
|
|
||||||
#include "gpio_object.h"
|
#include "gpio_object.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -0,0 +1,226 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* Copyright (c) 2006-2013 ARM Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#include "mbed_assert.h"
|
||||||
|
#include "pwmout_api.h"
|
||||||
|
#include "cmsis.h"
|
||||||
|
#include "pinmap.h"
|
||||||
|
#include "mbed_error.h"
|
||||||
|
|
||||||
|
// Ported from LPC824 and adapted.
|
||||||
|
|
||||||
|
#if DEVICE_PWMOUT
|
||||||
|
|
||||||
|
#define PWM_IRQn SCT_IRQn
|
||||||
|
|
||||||
|
// Bit flags for used SCT Outputs
|
||||||
|
static unsigned char sct_used = 0;
|
||||||
|
static int sct_inited = 0;
|
||||||
|
|
||||||
|
// Find available output channel
|
||||||
|
// Max number of PWM outputs is 4 on LPC812
|
||||||
|
static int get_available_sct() {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// Find available output channel 0..3
|
||||||
|
// Also need one Match register per channel
|
||||||
|
for (i = 0; i < CONFIG_SCT_nOU; i++) {
|
||||||
|
// for (i = 0; i < 4; i++) {
|
||||||
|
if ((sct_used & (1 << i)) == 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any Port pin may be used for PWM.
|
||||||
|
// Max number of PWM outputs is 4
|
||||||
|
void pwmout_init(pwmout_t* obj, PinName pin) {
|
||||||
|
MBED_ASSERT(pin != (uint32_t)NC);
|
||||||
|
|
||||||
|
int sct_n = get_available_sct();
|
||||||
|
if (sct_n == -1) {
|
||||||
|
error("No available SCT Output");
|
||||||
|
}
|
||||||
|
|
||||||
|
sct_used |= (1 << sct_n);
|
||||||
|
|
||||||
|
obj->pwm = (LPC_SCT_TypeDef*)LPC_SCT;
|
||||||
|
obj->pwm_ch = sct_n;
|
||||||
|
|
||||||
|
LPC_SCT_TypeDef* pwm = obj->pwm;
|
||||||
|
|
||||||
|
// Init SCT on first use
|
||||||
|
if (! sct_inited) {
|
||||||
|
sct_inited = 1;
|
||||||
|
|
||||||
|
// Enable the SCT clock
|
||||||
|
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
|
||||||
|
|
||||||
|
// Clear peripheral reset the SCT:
|
||||||
|
LPC_SYSCON->PRESETCTRL |= (1 << 8);
|
||||||
|
|
||||||
|
// Two 16-bit counters, autolimit (ie reset on Match_0)
|
||||||
|
pwm->CONFIG &= ~(0x1);
|
||||||
|
pwm->CONFIG |= (1 << 17);
|
||||||
|
|
||||||
|
// halt and clear the counter
|
||||||
|
pwm->CTRL_L |= (1 << 2) | (1 << 3);
|
||||||
|
|
||||||
|
// System Clock (30 Mhz) -> Prescaler -> us_ticker (1 MHz)
|
||||||
|
pwm->CTRL_L &= ~(0x7F << 5);
|
||||||
|
pwm->CTRL_L |= (((SystemCoreClock/1000000 - 1) & 0x7F) << 5);
|
||||||
|
|
||||||
|
pwm->EVENT[0].CTRL = (1 << 12) | 0; // Event_0 on Match_0
|
||||||
|
pwm->EVENT[0].STATE = 0xFFFFFFFF; // All states
|
||||||
|
|
||||||
|
// unhalt the counter:
|
||||||
|
// - clearing bit 2 of the CTRL register
|
||||||
|
pwm->CTRL_L &= ~(1 << 2);
|
||||||
|
|
||||||
|
// Not using IRQs
|
||||||
|
//NVIC_SetVector(PWM_IRQn, (uint32_t)pwm_irq_handler);
|
||||||
|
//NVIC_EnableIRQ(PWM_IRQn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// LPC81x has only one SCT and 4 Outputs
|
||||||
|
// LPC82x has only one SCT and 6 Outputs
|
||||||
|
// LPC1549 has 4 SCTs and 16 Outputs
|
||||||
|
switch(sct_n) {
|
||||||
|
case 0:
|
||||||
|
// SCTx_OUT0
|
||||||
|
LPC_SWM->PINASSIGN[6] &= ~0xFF000000;
|
||||||
|
LPC_SWM->PINASSIGN[6] |= (pin << 24);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
// SCTx_OUT1
|
||||||
|
LPC_SWM->PINASSIGN[7] &= ~0x000000FF;
|
||||||
|
LPC_SWM->PINASSIGN[7] |= (pin);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
// SCTx_OUT2
|
||||||
|
LPC_SWM->PINASSIGN[7] &= ~0x0000FF00;
|
||||||
|
LPC_SWM->PINASSIGN[7] |= (pin << 8);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
// SCTx_OUT3
|
||||||
|
LPC_SWM->PINASSIGN[7] &= ~0x00FF0000;
|
||||||
|
LPC_SWM->PINASSIGN[7] |= (pin << 16);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwm->EVENT[sct_n + 1].CTRL = (1 << 12) | (sct_n + 1); // Event_n on Match_n
|
||||||
|
pwm->EVENT[sct_n + 1].STATE = 0xFFFFFFFF; // All states
|
||||||
|
|
||||||
|
pwm->OUT[sct_n].SET = (1 << 0); // All PWM channels are SET on Event_0
|
||||||
|
pwm->OUT[sct_n].CLR = (1 << (sct_n + 1)); // PWM ch is CLRed on Event_(ch+1)
|
||||||
|
|
||||||
|
// default to 20ms: standard for servos, and fine for e.g. brightness control
|
||||||
|
pwmout_period_ms(obj, 20); // 20ms period
|
||||||
|
pwmout_write (obj, 0.0); // 0ms pulsewidth, dutycycle 0
|
||||||
|
}
|
||||||
|
|
||||||
|
void pwmout_free(pwmout_t* obj) {
|
||||||
|
// PWM channel is now free
|
||||||
|
sct_used &= ~(1 << obj->pwm_ch);
|
||||||
|
|
||||||
|
// Disable the SCT clock when all channels free
|
||||||
|
if (sct_used == 0) {
|
||||||
|
LPC_SYSCON->SYSAHBCLKCTRL &= ~(1 << 8);
|
||||||
|
sct_inited = 0;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set new dutycycle (0.0 .. 1.0)
|
||||||
|
void pwmout_write(pwmout_t* obj, float value) {
|
||||||
|
//value is new dutycycle
|
||||||
|
if (value < 0.0f) {
|
||||||
|
value = 0.0;
|
||||||
|
} else if (value > 1.0f) {
|
||||||
|
value = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Match_0 is PWM period. Compute new endtime of pulse for current channel
|
||||||
|
uint32_t t_off = (uint32_t)((float)(obj->pwm->MATCHREL[0].L) * value);
|
||||||
|
obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = t_off; // New endtime
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get dutycycle (0.0 .. 1.0)
|
||||||
|
float pwmout_read(pwmout_t* obj) {
|
||||||
|
uint32_t t_period = obj->pwm->MATCHREL[0].L;
|
||||||
|
|
||||||
|
//Sanity check
|
||||||
|
if (t_period == 0) {
|
||||||
|
return 0.0;
|
||||||
|
};
|
||||||
|
|
||||||
|
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L;
|
||||||
|
float v = (float)t_off/(float)t_period;
|
||||||
|
//Sanity check
|
||||||
|
return (v > 1.0f) ? (1.0f) : (v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the PWM period, keeping the duty cycle the same (for this channel only!).
|
||||||
|
void pwmout_period(pwmout_t* obj, float seconds){
|
||||||
|
pwmout_period_us(obj, seconds * 1000000.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the PWM period, keeping the duty cycle the same (for this channel only!).
|
||||||
|
void pwmout_period_ms(pwmout_t* obj, int ms) {
|
||||||
|
pwmout_period_us(obj, ms * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the PWM period, keeping the duty cycle the same (for this channel only!).
|
||||||
|
void pwmout_period_us(pwmout_t* obj, int us) {
|
||||||
|
|
||||||
|
uint32_t t_period = obj->pwm->MATCHREL[0].L; // Current PWM period
|
||||||
|
obj->pwm->MATCHREL[0].L = (uint64_t)us; // New PWM period
|
||||||
|
|
||||||
|
//Keep the dutycycle for the new PWM period
|
||||||
|
//Should really do this for all active channels!!
|
||||||
|
//This problem exists in all mbed libs.
|
||||||
|
|
||||||
|
//Sanity check
|
||||||
|
if (t_period == 0) {
|
||||||
|
return;
|
||||||
|
// obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = 0; // New endtime for this channel
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L;
|
||||||
|
float v = (float)t_off/(float)t_period;
|
||||||
|
obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = (uint64_t)((float)us * (float)v); // New endtime for this channel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Set pulsewidth
|
||||||
|
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
|
||||||
|
pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set pulsewidth
|
||||||
|
void pwmout_pulsewidth_ms(pwmout_t* obj, int ms){
|
||||||
|
pwmout_pulsewidth_us(obj, ms * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Set pulsewidth
|
||||||
|
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
|
||||||
|
|
||||||
|
//Should add Sanity check to make sure pulsewidth < period!
|
||||||
|
obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = (uint64_t)us; // New endtime for this channel
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -17,77 +17,105 @@
|
||||||
#include "us_ticker_api.h"
|
#include "us_ticker_api.h"
|
||||||
#include "PeripheralNames.h"
|
#include "PeripheralNames.h"
|
||||||
|
|
||||||
#define US_TICKER_TIMER_IRQn SCT_IRQn
|
//New, using MRT instead of SCT, needed to free up SCT for PWM
|
||||||
|
//Ported from LPC824 libs
|
||||||
|
static int us_ticker_inited = 0;
|
||||||
|
unsigned int ticker_fullcount_us;
|
||||||
|
unsigned long int ticker_expired_count_us = 0;
|
||||||
|
int MRT_Clock_MHz;
|
||||||
|
|
||||||
int us_ticker_inited = 0;
|
#define US_TICKER_TIMER_IRQn MRT_IRQn
|
||||||
|
|
||||||
void us_ticker_init(void) {
|
void us_ticker_init(void) {
|
||||||
if (us_ticker_inited) return;
|
|
||||||
|
if (us_ticker_inited)
|
||||||
|
return;
|
||||||
|
|
||||||
us_ticker_inited = 1;
|
us_ticker_inited = 1;
|
||||||
|
|
||||||
// Enable the SCT clock
|
// Calculate MRT clock value (MRT has no prescaler)
|
||||||
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
|
MRT_Clock_MHz = (SystemCoreClock / 1000000);
|
||||||
|
// Calculate fullcounter value in us (MRT has 31 bits and clock is 30 MHz)
|
||||||
|
ticker_fullcount_us = 0x80000000UL/MRT_Clock_MHz;
|
||||||
|
|
||||||
// Clear peripheral reset the SCT:
|
// Enable the MRT clock
|
||||||
LPC_SYSCON->PRESETCTRL |= (1 << 8);
|
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 10);
|
||||||
|
|
||||||
// Unified counter (32 bits)
|
// Clear peripheral reset the MRT
|
||||||
LPC_SCT->CONFIG |= 1;
|
LPC_SYSCON->PRESETCTRL |= (1 << 7);
|
||||||
|
|
||||||
// halt and clear the counter
|
// Force load interval value (Bit 0-30 is interval value, Bit 31 is Force Load bit)
|
||||||
LPC_SCT->CTRL_L |= (1 << 2) | (1 << 3);
|
LPC_MRT->INTVAL0 = 0xFFFFFFFFUL;
|
||||||
|
// Enable Ch0 interrupt, Mode 0 is Repeat Interrupt
|
||||||
|
LPC_MRT->CTRL0 = (0x0 << 1) | (0x1 << 0);
|
||||||
|
|
||||||
// System Clock (12)MHz -> us_ticker (1)MHz
|
// Force load interval value (Bit 0-30 is interval value, Bit 31 is Force Load bit)
|
||||||
LPC_SCT->CTRL_L |= ((SystemCoreClock/1000000 - 1) << 5);
|
LPC_MRT->INTVAL1 = 0x80000000UL;
|
||||||
|
// Disable ch1 interrupt, Mode 0 is Repeat Interrupt
|
||||||
// unhalt the counter:
|
LPC_MRT->CTRL1 = (0x0 << 1) | (0x0 << 0);
|
||||||
// - clearing bit 2 of the CTRL register
|
|
||||||
LPC_SCT->CTRL_L &= ~(1 << 2);
|
|
||||||
|
|
||||||
|
// Set MRT interrupt vector
|
||||||
NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
|
NVIC_SetVector(US_TICKER_TIMER_IRQn, (uint32_t)us_ticker_irq_handler);
|
||||||
NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
|
NVIC_EnableIRQ(US_TICKER_TIMER_IRQn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TIMER0 is used for us ticker and timers (Timer, wait(), wait_us() etc)
|
||||||
uint32_t us_ticker_read() {
|
uint32_t us_ticker_read() {
|
||||||
|
|
||||||
if (!us_ticker_inited)
|
if (!us_ticker_inited)
|
||||||
us_ticker_init();
|
us_ticker_init();
|
||||||
|
|
||||||
return LPC_SCT->COUNT_U;
|
// Generate ticker value
|
||||||
|
// MRT source clock is SystemCoreClock (30MHz) and MRT is a 31-bit countdown timer
|
||||||
|
// Calculate expected value using current count and number of expired times to mimic a 32bit timer @ 1 MHz
|
||||||
|
//
|
||||||
|
// ticker_expired_count_us
|
||||||
|
// The variable ticker_expired_count_us keeps track of the number of 31bits overflows (counted by TIMER0) and
|
||||||
|
// corrects that back to us counts.
|
||||||
|
//
|
||||||
|
// (0x7FFFFFFFUL - LPC_MRT->TIMER0)/MRT_Clock_MHz
|
||||||
|
// The counter is a 31bit downcounter from 7FFFFFFF so correct to actual count-up value and correct
|
||||||
|
// for 30 counts per us.
|
||||||
|
//
|
||||||
|
// Added up these 2 parts result in current us time returned as 32 bits.
|
||||||
|
return (0x7FFFFFFFUL - LPC_MRT->TIMER0)/MRT_Clock_MHz + ticker_expired_count_us;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TIMER1 is used for Timestamped interrupts (Ticker(), Timeout())
|
||||||
void us_ticker_set_interrupt(timestamp_t timestamp) {
|
void us_ticker_set_interrupt(timestamp_t timestamp) {
|
||||||
// halt the counter:
|
|
||||||
// - setting bit 2 of the CTRL register
|
|
||||||
LPC_SCT->CTRL_L |= (1 << 2);
|
|
||||||
|
|
||||||
// set timestamp in compare register
|
// MRT source clock is SystemCoreClock (30MHz) and MRT is a 31-bit countdown timer
|
||||||
LPC_SCT->MATCH[0].U = (uint32_t)timestamp;
|
// Force load interval value (Bit 0-30 is interval value, Bit 31 is Force Load bit)
|
||||||
|
// Note: The MRT has less counter headroom available than the typical mbed 32bit timer @ 1 MHz.
|
||||||
|
// The calculated counter interval until the next timestamp will be truncated and an
|
||||||
|
// 'early' interrupt will be generated in case the max required count interval exceeds
|
||||||
|
// the available 31 bits space. However, the mbed us_ticker interrupt handler will
|
||||||
|
// check current time against the next scheduled timestamp and simply re-issue the
|
||||||
|
// same interrupt again when needed. The calculated counter interval will now be smaller.
|
||||||
|
LPC_MRT->INTVAL1 = (((timestamp - us_ticker_read()) * MRT_Clock_MHz) | 0x80000000UL);
|
||||||
|
|
||||||
// unhalt the counter:
|
// Enable interrupt
|
||||||
// - clearing bit 2 of the CTRL register
|
LPC_MRT->CTRL1 |= 1;
|
||||||
LPC_SCT->CTRL_L &= ~(1 << 2);
|
}
|
||||||
|
|
||||||
// if events are not enabled, enable them
|
//Disable Timestamped interrupts triggered by TIMER1
|
||||||
if (!(LPC_SCT->EVEN & 0x01)) {
|
void us_ticker_disable_interrupt() {
|
||||||
|
//Timer1 for Timestamped interrupts (31 bits downcounter @ SystemCoreClock)
|
||||||
|
LPC_MRT->CTRL1 &= ~1;
|
||||||
|
}
|
||||||
|
|
||||||
// comb mode = match only
|
void us_ticker_clear_interrupt() {
|
||||||
LPC_SCT->EVENT[0].CTRL = (1 << 12);
|
|
||||||
|
|
||||||
// ref manual:
|
//Timer1 for Timestamped interrupts (31 bits downcounter @ SystemCoreClock)
|
||||||
// In simple applications that do not
|
if (LPC_MRT->STAT1 & 1)
|
||||||
// use states, write 0x01 to this
|
LPC_MRT->STAT1 = 1;
|
||||||
// register to enable an event
|
|
||||||
LPC_SCT->EVENT[0].STATE |= 0x1;
|
|
||||||
|
|
||||||
// enable events
|
//Timer0 for us counter (31 bits downcounter @ SystemCoreClock)
|
||||||
LPC_SCT->EVEN |= 0x1;
|
if (LPC_MRT->STAT0 & 1) {
|
||||||
|
LPC_MRT->STAT0 = 1;
|
||||||
|
// ticker_expired_count_us = (ticker_expired * 0x80000000UL) / MRT_Clock_MHz
|
||||||
|
// The variable ticker_expired_count_us keeps track of the number of 31bits overflows (counted by TIMER0) and
|
||||||
|
// the multiplication/division corrects that back to us counts.
|
||||||
|
ticker_expired_count_us += ticker_fullcount_us;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void us_ticker_disable_interrupt(void) {
|
|
||||||
LPC_SCT->EVEN &= ~1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void us_ticker_clear_interrupt(void) {
|
|
||||||
LPC_SCT->EVFLAG = 1;
|
|
||||||
}
|
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
// <i> Defines the number of threads with user-provided stack size.
|
// <i> Defines the number of threads with user-provided stack size.
|
||||||
// <i> Default: 0
|
// <i> Default: 0
|
||||||
#ifndef OS_PRIVCNT
|
#ifndef OS_PRIVCNT
|
||||||
#define OS_PRIVCNT 8
|
#define OS_PRIVCNT 10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// <o>Total stack size [bytes] for threads with user-provided stack size <0-4096:8><#/4>
|
// <o>Total stack size [bytes] for threads with user-provided stack size <0-4096:8><#/4>
|
||||||
|
|
|
@ -27,7 +27,8 @@ class IAREmbeddedWorkbench(Exporter):
|
||||||
'LPC11U24',
|
'LPC11U24',
|
||||||
'LPC11U35_401',
|
'LPC11U35_401',
|
||||||
'LPC11U35_501',
|
'LPC11U35_501',
|
||||||
'LPCCAPPUCCINO',
|
#Removed LPCCAPPUCCINO linker file and startup file missing
|
||||||
|
#'LPCCAPPUCCINO',
|
||||||
'LPC1114',
|
'LPC1114',
|
||||||
'LPC1549',
|
'LPC1549',
|
||||||
'LPC812',
|
'LPC812',
|
||||||
|
@ -53,7 +54,7 @@ class IAREmbeddedWorkbench(Exporter):
|
||||||
'NUCLEO_F411RE',
|
'NUCLEO_F411RE',
|
||||||
'NUCLEO_L053R8',
|
'NUCLEO_L053R8',
|
||||||
'NUCLEO_L152RE',
|
'NUCLEO_L152RE',
|
||||||
'STM32F407',
|
#'STM32F407', Fails to build same for GCC
|
||||||
'MTS_MDOT_F405RG',
|
'MTS_MDOT_F405RG',
|
||||||
'MTS_MDOT_F411RE',
|
'MTS_MDOT_F411RE',
|
||||||
'MTS_DRAGONFLY_F411RE',
|
'MTS_DRAGONFLY_F411RE',
|
||||||
|
@ -79,3 +80,4 @@ class IAREmbeddedWorkbench(Exporter):
|
||||||
}
|
}
|
||||||
self.gen_file('iar_%s.ewp.tmpl' % self.target.lower(), ctx, '%s.ewp' % self.program_name)
|
self.gen_file('iar_%s.ewp.tmpl' % self.target.lower(), ctx, '%s.ewp' % self.program_name)
|
||||||
self.gen_file('iar.eww.tmpl', ctx, '%s.eww' % self.program_name)
|
self.gen_file('iar.eww.tmpl', ctx, '%s.eww' % self.program_name)
|
||||||
|
self.gen_file('iar_%s.ewd.tmpl' % self.target.lower(), ctx, '%s.ewd' % self.program_name)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -747,11 +747,11 @@
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>IlinkUseExtraOptions</name>
|
<name>IlinkUseExtraOptions</name>
|
||||||
<state>0</state>
|
<state>1</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>IlinkExtraOptions</name>
|
<name>IlinkExtraOptions</name>
|
||||||
<state></state>
|
<state>--skip_dynamic_initialization</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>IlinkLowLevelInterfaceSlave</name>
|
<name>IlinkLowLevelInterfaceSlave</name>
|
||||||
|
@ -1693,11 +1693,11 @@
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>IlinkUseExtraOptions</name>
|
<name>IlinkUseExtraOptions</name>
|
||||||
<state>0</state>
|
<state>1</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>IlinkExtraOptions</name>
|
<name>IlinkExtraOptions</name>
|
||||||
<state></state>
|
<state>--skip_dynamic_initialization</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>IlinkLowLevelInterfaceSlave</name>
|
<name>IlinkLowLevelInterfaceSlave</name>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -60,7 +60,7 @@
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>FPU</name>
|
<name>FPU</name>
|
||||||
<version>2</version>
|
<version>3</version>
|
||||||
<state>5</state>
|
<state>5</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>OGChipSelectEditMenu</name>
|
<name>OGChipSelectEditMenu</name>
|
||||||
<state>STM32F303RE ST STM32F303RE</state>
|
<state>STM32F303xE ST STM32F303xE</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>GenLowLevelInterface</name>
|
<name>GenLowLevelInterface</name>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -30,7 +30,7 @@
|
||||||
<option>
|
<option>
|
||||||
<name>Variant</name>
|
<name>Variant</name>
|
||||||
<version>21</version>
|
<version>21</version>
|
||||||
<state>38</state>
|
<state>40</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>GEndianMode</name>
|
<name>GEndianMode</name>
|
||||||
|
@ -60,8 +60,8 @@
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>FPU</name>
|
<name>FPU</name>
|
||||||
<version>2</version>
|
<version>3</version>
|
||||||
<state>0</state>
|
<state>5</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>OGCoreOrChip</name>
|
<name>OGCoreOrChip</name>
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>OGChipSelectEditMenu</name>
|
<name>OGChipSelectEditMenu</name>
|
||||||
<state>STM32F401RE ST STM32F401RE</state>
|
<state>STM32F401xE ST STM32F401xE</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>GenLowLevelInterface</name>
|
<name>GenLowLevelInterface</name>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -37,6 +37,13 @@ class EchoTest():
|
||||||
selftest.mbed.flush()
|
selftest.mbed.flush()
|
||||||
selftest.notify("HOST: Starting the ECHO test")
|
selftest.notify("HOST: Starting the ECHO test")
|
||||||
result = True
|
result = True
|
||||||
|
|
||||||
|
""" This ensures that there are no parasites left in the serial buffer.
|
||||||
|
"""
|
||||||
|
for i in range(0, 2):
|
||||||
|
selftest.mbed.serial_write("\n")
|
||||||
|
c = selftest.mbed.serial_readline()
|
||||||
|
|
||||||
for i in range(0, self.TEST_LOOP_COUNT):
|
for i in range(0, self.TEST_LOOP_COUNT):
|
||||||
TEST_STRING = str(uuid.uuid4()) + "\n"
|
TEST_STRING = str(uuid.uuid4()) + "\n"
|
||||||
selftest.mbed.serial_write(TEST_STRING)
|
selftest.mbed.serial_write(TEST_STRING)
|
||||||
|
|
|
@ -415,7 +415,7 @@ class K20D50M(Target):
|
||||||
self.detect_code = ["0230"]
|
self.detect_code = ["0230"]
|
||||||
|
|
||||||
class TEENSY3_1(Target):
|
class TEENSY3_1(Target):
|
||||||
OUTPUT_EXT = '.hex'
|
OUTPUT_EXT = 'hex'
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
Target.__init__(self)
|
Target.__init__(self)
|
||||||
|
@ -751,7 +751,7 @@ class NRF51822(Target):
|
||||||
'offset' : 0x14000
|
'offset' : 0x14000
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
OUTPUT_EXT = '.hex'
|
OUTPUT_EXT = 'hex'
|
||||||
MERGE_SOFT_DEVICE = True
|
MERGE_SOFT_DEVICE = True
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -633,6 +633,8 @@ class mbedToolchain:
|
||||||
|
|
||||||
def link_program(self, r, tmp_path, name):
|
def link_program(self, r, tmp_path, name):
|
||||||
ext = 'bin'
|
ext = 'bin'
|
||||||
|
if hasattr(self.target, 'OUTPUT_EXT'):
|
||||||
|
ext = self.target.OUTPUT_EXT
|
||||||
|
|
||||||
if hasattr(self.target, 'OUTPUT_NAMING'):
|
if hasattr(self.target, 'OUTPUT_NAMING'):
|
||||||
self.var("binary_naming", self.target.OUTPUT_NAMING)
|
self.var("binary_naming", self.target.OUTPUT_NAMING)
|
||||||
|
@ -641,7 +643,6 @@ class mbedToolchain:
|
||||||
ext = ext[0:3]
|
ext = ext[0:3]
|
||||||
|
|
||||||
filename = name+'.'+ext
|
filename = name+'.'+ext
|
||||||
|
|
||||||
elf = join(tmp_path, name + '.elf')
|
elf = join(tmp_path, name + '.elf')
|
||||||
bin = join(tmp_path, filename)
|
bin = join(tmp_path, filename)
|
||||||
|
|
||||||
|
@ -657,9 +658,6 @@ class mbedToolchain:
|
||||||
self.var("compile_succeded", True)
|
self.var("compile_succeded", True)
|
||||||
self.var("binary", filename)
|
self.var("binary", filename)
|
||||||
|
|
||||||
if hasattr(self.target, 'OUTPUT_EXT'):
|
|
||||||
bin = bin.replace('.bin', self.target.OUTPUT_EXT)
|
|
||||||
|
|
||||||
return bin
|
return bin
|
||||||
|
|
||||||
def default_cmd(self, command):
|
def default_cmd(self, command):
|
||||||
|
|
Loading…
Reference in New Issue