mirror of https://github.com/ARMmbed/mbed-os.git
Merge branch 'master' of https://github.com/mbedmicro/mbed
commit
d41f3f335f
|
@ -24,14 +24,15 @@
|
|||
#include "sleep_api.h"
|
||||
#include "sleepmodes.h"
|
||||
|
||||
static bool rtc_inited = false;
|
||||
static time_t time_base = 0;
|
||||
static uint32_t useflags = 0;
|
||||
static bool rtc_inited = false;
|
||||
static time_t time_base = 0;
|
||||
static uint32_t useflags = 0;
|
||||
static uint32_t time_extend = 0;
|
||||
|
||||
static void (*comp0_handler)(void) = NULL;
|
||||
|
||||
#define RTC_LEAST_ACTIVE_SLEEPMODE EM2
|
||||
|
||||
#define RTC_LEAST_ACTIVE_SLEEPMODE EM2
|
||||
#define RTC_NUM_BITS (24)
|
||||
|
||||
void RTC_IRQHandler(void)
|
||||
{
|
||||
|
@ -39,8 +40,8 @@ void RTC_IRQHandler(void)
|
|||
flags = RTC_IntGet();
|
||||
if (flags & RTC_IF_OF) {
|
||||
RTC_IntClear(RTC_IF_OF);
|
||||
/* RTC has overflowed (24 bits). Use time_base as software counter for upper 8 bits. */
|
||||
time_base += 1 << 24;
|
||||
/* RTC has overflowed (24 bits). Use time_extend as software counter for 32 more bits. */
|
||||
time_extend += 1;
|
||||
}
|
||||
if (flags & RTC_IF_COMP0) {
|
||||
RTC_IntClear(RTC_IF_COMP0);
|
||||
|
@ -50,6 +51,20 @@ void RTC_IRQHandler(void)
|
|||
}
|
||||
}
|
||||
|
||||
uint32_t rtc_get_32bit(void)
|
||||
{
|
||||
return (RTC_CounterGet() + (time_extend << RTC_NUM_BITS));
|
||||
}
|
||||
|
||||
uint64_t rtc_get_full(void)
|
||||
{
|
||||
uint64_t ticks = 0;
|
||||
ticks += time_extend;
|
||||
ticks = ticks << RTC_NUM_BITS;
|
||||
ticks += RTC_CounterGet();
|
||||
return ticks;
|
||||
}
|
||||
|
||||
void rtc_set_comp0_handler(uint32_t handler)
|
||||
{
|
||||
comp0_handler = (void (*)(void)) handler;
|
||||
|
@ -126,18 +141,23 @@ int rtc_isenabled(void)
|
|||
|
||||
time_t rtc_read(void)
|
||||
{
|
||||
return (time_t) ((RTC_CounterGet() + time_base) >> RTC_FREQ_SHIFT);
|
||||
return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT) + time_base;
|
||||
}
|
||||
|
||||
time_t rtc_read_uncompensated(void)
|
||||
{
|
||||
return (time_t) (rtc_get_full() >> RTC_FREQ_SHIFT);
|
||||
}
|
||||
|
||||
void rtc_write(time_t t)
|
||||
{
|
||||
/* We have to check that the RTC did not tick while doing this. */
|
||||
/* If the RTC ticks we just redo this. */
|
||||
uint32_t rtc_count;
|
||||
uint32_t time;
|
||||
do {
|
||||
rtc_count = RTC_CounterGet();
|
||||
time_base = (t << RTC_FREQ_SHIFT) - rtc_count;
|
||||
} while (rtc_count != RTC_CounterGet());
|
||||
time = rtc_read_uncompensated();
|
||||
time_base = t - time;
|
||||
} while (time != rtc_read_uncompensated());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -767,8 +767,24 @@ static void spi_activate_dma(spi_t *obj, void* rxdata, void* txdata, int tx_leng
|
|||
DMA_CfgDescr_TypeDef rxDescrCfg;
|
||||
DMA_CfgDescr_TypeDef txDescrCfg;
|
||||
|
||||
/* Split up transfers if the tx length is larger than what the DMA supports. */
|
||||
const int DMA_MAX_TRANSFER = (_DMA_CTRL_N_MINUS_1_MASK >> _DMA_CTRL_N_MINUS_1_SHIFT);
|
||||
|
||||
if (tx_length > DMA_MAX_TRANSFER) {
|
||||
uint32_t max_length = DMA_MAX_TRANSFER;
|
||||
|
||||
/* Make sure only an even amount of bytes are transferred
|
||||
if the width is larger than 8 bits. */
|
||||
if (obj->spi.bits > 8) {
|
||||
max_length = DMA_MAX_TRANSFER - (DMA_MAX_TRANSFER & 0x01);
|
||||
}
|
||||
|
||||
/* Update length for current transfer. */
|
||||
tx_length = max_length;
|
||||
}
|
||||
|
||||
/* Save amount of TX done by DMA */
|
||||
obj->tx_buff.pos = tx_length;
|
||||
obj->tx_buff.pos += tx_length;
|
||||
|
||||
if(obj->spi.bits != 9) {
|
||||
/* Only activate RX DMA if a receive buffer is specified */
|
||||
|
@ -966,6 +982,18 @@ uint32_t spi_irq_handler_asynch(spi_t* obj)
|
|||
if (obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_ALLOCATED || obj->spi.dmaOptionsTX.dmaUsageState == DMA_USAGE_TEMPORARY_ALLOCATED) {
|
||||
/* DMA implementation */
|
||||
|
||||
/* If there is still data in the TX buffer, setup a new transfer. */
|
||||
if (obj->tx_buff.pos < obj->tx_buff.length) {
|
||||
/* Find position and remaining length without modifying tx_buff. */
|
||||
void* tx_pointer = obj->tx_buff.buffer + obj->tx_buff.pos;
|
||||
uint32_t tx_length = obj->tx_buff.length - obj->tx_buff.pos;
|
||||
|
||||
/* Begin transfer. Rely on spi_activate_dma to split up the transfer further. */
|
||||
spi_activate_dma(obj, obj->rx_buff.buffer, tx_pointer, tx_length, obj->rx_buff.length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If there is an RX transfer ongoing, wait for it to finish */
|
||||
if (DMA_ChannelEnabled(obj->spi.dmaOptionsRX.dmaChannel)) {
|
||||
/* Check if we need to kick off TX transfer again to force more incoming data. */
|
||||
|
|
Loading…
Reference in New Issue