Merge branch 'master' into pinecil
This commit is contained in:
@@ -7,8 +7,7 @@
|
||||
#include <I2C_Wrapper.hpp>
|
||||
#include "BSP.h"
|
||||
#include "Setup.h"
|
||||
#define I2CUSESDMA
|
||||
SemaphoreHandle_t FRToSI2C::I2CSemaphore;
|
||||
SemaphoreHandle_t FRToSI2C::I2CSemaphore = nullptr;
|
||||
StaticSemaphore_t FRToSI2C::xSemaphoreBuffer;
|
||||
|
||||
void FRToSI2C::CpltCallback() {
|
||||
@@ -21,45 +20,22 @@ void FRToSI2C::CpltCallback() {
|
||||
bool FRToSI2C::Mem_Read(uint16_t DevAddress, uint16_t MemAddress,
|
||||
uint8_t *pData, uint16_t Size) {
|
||||
|
||||
if (I2CSemaphore == NULL) {
|
||||
// no RToS, run blocking code
|
||||
HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT,
|
||||
pData, Size, 5000);
|
||||
return true;
|
||||
} else {
|
||||
// RToS is active, run threading
|
||||
// Get the mutex so we can use the I2C port
|
||||
// Wait up to 1 second for the mutex
|
||||
if (xSemaphoreTake(I2CSemaphore, (TickType_t)500) == pdTRUE) {
|
||||
#ifdef I2CUSESDMA
|
||||
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress,
|
||||
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
|
||||
if (!lock())
|
||||
return false;
|
||||
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress,
|
||||
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
|
||||
|
||||
I2C_Unstick();
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
return false;
|
||||
} else {
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
|
||||
if (HAL_I2C_Mem_Read(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT, pData, Size,
|
||||
5000)==HAL_OK){
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
return true;
|
||||
}
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
return false;
|
||||
#endif
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
I2C_Unstick();
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
unlock();
|
||||
return true;
|
||||
|
||||
}
|
||||
void FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
|
||||
Mem_Write(address, reg, &data, 1);
|
||||
bool FRToSI2C::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) {
|
||||
return Mem_Write(address, reg, &data, 1);
|
||||
}
|
||||
|
||||
uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
|
||||
@@ -67,67 +43,55 @@ uint8_t FRToSI2C::I2C_RegisterRead(uint8_t add, uint8_t reg) {
|
||||
Mem_Read(add, reg, tx_data, 1);
|
||||
return tx_data[0];
|
||||
}
|
||||
void FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||
bool FRToSI2C::Mem_Write(uint16_t DevAddress, uint16_t MemAddress,
|
||||
uint8_t *pData, uint16_t Size) {
|
||||
|
||||
if (I2CSemaphore == NULL) {
|
||||
// no RToS, run blocking code
|
||||
HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress, I2C_MEMADD_SIZE_8BIT,
|
||||
pData, Size, 5000);
|
||||
} else {
|
||||
// RToS is active, run threading
|
||||
// Get the mutex so we can use the I2C port
|
||||
// Wait up to 1 second for the mutex
|
||||
if (xSemaphoreTake(I2CSemaphore, (TickType_t)500) == pdTRUE) {
|
||||
if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress,
|
||||
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
|
||||
if (!lock())
|
||||
return false;
|
||||
if (HAL_I2C_Mem_Write(&hi2c1, DevAddress, MemAddress,
|
||||
I2C_MEMADD_SIZE_8BIT, pData, Size, 500) != HAL_OK) {
|
||||
|
||||
I2C_Unstick();
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
}
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
|
||||
}
|
||||
I2C_Unstick();
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
if (I2CSemaphore == NULL) {
|
||||
// no RToS, run blocking code
|
||||
HAL_I2C_Master_Transmit(&hi2c1, DevAddress, pData, Size, 5000);
|
||||
} else {
|
||||
// RToS is active, run threading
|
||||
// Get the mutex so we can use the I2C port
|
||||
// Wait up to 1 second for the mutex
|
||||
if (xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE) {
|
||||
#ifdef I2CUSESDMA
|
||||
|
||||
if (HAL_I2C_Master_Transmit_DMA(&hi2c1, DevAddress, pData, Size)
|
||||
!= HAL_OK) {
|
||||
|
||||
I2C_Unstick();
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
|
||||
}
|
||||
#else
|
||||
HAL_I2C_Master_Transmit(&hi2c1, DevAddress, pData, Size, 5000);
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
}
|
||||
bool FRToSI2C::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
if (!lock())
|
||||
return false;
|
||||
if (HAL_I2C_Master_Transmit_DMA(&hi2c1, DevAddress, pData, Size)
|
||||
!= HAL_OK) {
|
||||
I2C_Unstick();
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FRToSI2C::probe(uint16_t DevAddress) {
|
||||
if (!lock())
|
||||
return false;
|
||||
uint8_t buffer[1];
|
||||
return HAL_I2C_Mem_Read(&hi2c1, DevAddress, 0x0F, I2C_MEMADD_SIZE_8BIT,
|
||||
buffer, 1, 1000) == HAL_OK;
|
||||
|
||||
bool worked = HAL_I2C_Mem_Read(&hi2c1, DevAddress, 0x0F,
|
||||
I2C_MEMADD_SIZE_8BIT, buffer, 1, 1000) == HAL_OK;
|
||||
unlock();
|
||||
return worked;
|
||||
}
|
||||
|
||||
void FRToSI2C::I2C_Unstick() {
|
||||
unstick_I2C();
|
||||
}
|
||||
|
||||
void FRToSI2C::unlock() {
|
||||
|
||||
xSemaphoreGive(I2CSemaphore);
|
||||
}
|
||||
|
||||
bool FRToSI2C::lock() {
|
||||
|
||||
return xSemaphoreTake(I2CSemaphore, (TickType_t)50) == pdTRUE;
|
||||
}
|
||||
|
||||
@@ -30,12 +30,16 @@ static void MX_TIM2_Init(void);
|
||||
static void MX_DMA_Init(void);
|
||||
static void MX_GPIO_Init(void);
|
||||
static void MX_ADC2_Init(void);
|
||||
|
||||
#define SWD_ENABLE
|
||||
void Setup_HAL() {
|
||||
SystemClock_Config();
|
||||
__HAL_AFIO_REMAP_SWJ_DISABLE()
|
||||
;
|
||||
// __HAL_AFIO_REMAP_SWJ_NOJTAG();
|
||||
|
||||
#ifndef SWD_ENABLE
|
||||
__HAL_AFIO_REMAP_SWJ_DISABLE();
|
||||
#else
|
||||
__HAL_AFIO_REMAP_SWJ_NOJTAG();
|
||||
#endif
|
||||
|
||||
MX_GPIO_Init();
|
||||
MX_DMA_Init();
|
||||
MX_I2C1_Init();
|
||||
@@ -244,7 +248,7 @@ static void MX_IWDG_Init(void) {
|
||||
hiwdg.Instance = IWDG;
|
||||
hiwdg.Init.Prescaler = IWDG_PRESCALER_256;
|
||||
hiwdg.Init.Reload = 100;
|
||||
#ifndef LOCAL_BUILD
|
||||
#ifndef SWD_ENABLE
|
||||
HAL_IWDG_Init(&hiwdg);
|
||||
#endif
|
||||
}
|
||||
@@ -425,8 +429,10 @@ static void MX_GPIO_Init(void) {
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
#ifdef MODEL_TS100
|
||||
/* Pull USB lines low to disable, pull down debug too*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_13;
|
||||
#ifndef SWD_ENABLE
|
||||
/* Pull USB and SWD lines low to prevent enumeration attempts and EMI affecting
|
||||
* the debug core */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
@@ -434,6 +440,12 @@ static void MX_GPIO_Init(void) {
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_13, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_14, GPIO_PIN_RESET);
|
||||
#else
|
||||
/* Make all lines affecting SWD floating to allow debugging */
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_13;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
#endif
|
||||
#else
|
||||
/* TS80 */
|
||||
/* Leave USB lines open circuit*/
|
||||
|
||||
@@ -9,21 +9,21 @@
|
||||
#include "BSP.h"
|
||||
#include "string.h"
|
||||
#include "stm32f1xx_hal.h"
|
||||
/*Flash start OR'ed with the maximum amount of flash - 1024 bytes*/
|
||||
/*We use the last 1024 byte page*/
|
||||
#define FLASH_ADDR (0x8000000 |0xFC00)
|
||||
|
||||
static uint16_t settings_page[512] __attribute__ ((section (".settings_page")));
|
||||
|
||||
uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
|
||||
FLASH_EraseInitTypeDef pEraseInit;
|
||||
pEraseInit.TypeErase = FLASH_TYPEERASE_PAGES;
|
||||
pEraseInit.Banks = FLASH_BANK_1;
|
||||
pEraseInit.NbPages = 1;
|
||||
pEraseInit.PageAddress = FLASH_ADDR;
|
||||
pEraseInit.PageAddress = (uint32_t)settings_page;
|
||||
uint32_t failingAddress = 0;
|
||||
resetWatchdog();
|
||||
__HAL_FLASH_CLEAR_FLAG(
|
||||
FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR | FLASH_FLAG_BSY);
|
||||
HAL_FLASH_Unlock();
|
||||
HAL_Delay(10);
|
||||
HAL_Delay(1);
|
||||
resetWatchdog();
|
||||
HAL_FLASHEx_Erase(&pEraseInit, &failingAddress);
|
||||
//^ Erase the page of flash (1024 bytes on this stm32)
|
||||
@@ -33,7 +33,7 @@ uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
|
||||
HAL_FLASH_Unlock();
|
||||
for (uint8_t i = 0; i < (length / 2); i++) {
|
||||
resetWatchdog();
|
||||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FLASH_ADDR + (i * 2),
|
||||
HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, (uint32_t)&settings_page[i],
|
||||
data[i]);
|
||||
}
|
||||
HAL_FLASH_Lock();
|
||||
@@ -42,8 +42,5 @@ uint8_t flash_save_buffer(const uint8_t *buffer, const uint16_t length) {
|
||||
|
||||
void flash_read_buffer(uint8_t *buffer, const uint16_t length) {
|
||||
|
||||
uint16_t *data = (uint16_t*) buffer;
|
||||
for (uint8_t i = 0; i < (length / 2); i++) {
|
||||
data[i] = *((uint16_t*) (FLASH_ADDR + (i * 2)));
|
||||
}
|
||||
memcpy(buffer, settings_page, length);
|
||||
}
|
||||
|
||||
@@ -143,23 +143,13 @@ void fusb_send_hardrst() {
|
||||
}
|
||||
|
||||
void fusb_setup() {
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 12, 0);
|
||||
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
|
||||
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
if (!I2CBB::lock2()) {
|
||||
return;
|
||||
}
|
||||
if (!I2CBB::lock2()) {
|
||||
return;
|
||||
}
|
||||
/* Fully reset the FUSB302B */
|
||||
fusb_write_byte( FUSB_RESET, FUSB_RESET_SW_RES);
|
||||
osDelay(2);
|
||||
// fusb_write_byte( FUSB_RESET, FUSB_RESET_SW_RES);
|
||||
// osDelay(2);
|
||||
if (!fusb_read_id()) {
|
||||
return;
|
||||
}
|
||||
@@ -200,10 +190,16 @@ void fusb_setup() {
|
||||
fusb_write_byte( FUSB_SWITCHES1, 0x26);
|
||||
fusb_write_byte( FUSB_SWITCHES0, 0x0B);
|
||||
}
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
I2CBB::unlock2();
|
||||
}
|
||||
I2CBB::unlock2();
|
||||
fusb_reset();
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 10, 0);
|
||||
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
|
||||
}
|
||||
|
||||
void fusb_get_status(union fusb_status *status) {
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
#include "BSP.h"
|
||||
#include "OLED.hpp"
|
||||
// Second last page of flash set aside for logo image.
|
||||
#define FLASH_LOGOADDR (0x8000000 | 0xF800)
|
||||
|
||||
static uint8_t logo_page[1024] __attribute__ ((section (".logo_page")));
|
||||
|
||||
// Logo header signature.
|
||||
#define LOGO_HEADER_VALUE 0xF00DAA55
|
||||
@@ -16,11 +16,11 @@
|
||||
uint8_t showBootLogoIfavailable() {
|
||||
// Do not show logo data if signature is not found.
|
||||
if (LOGO_HEADER_VALUE
|
||||
!= *(reinterpret_cast<const uint32_t*>(FLASH_LOGOADDR))) {
|
||||
!= *(reinterpret_cast<const uint32_t*>(logo_page))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
OLED::drawAreaSwapped(0, 0, 96, 16, (uint8_t*) (FLASH_LOGOADDR + 4));
|
||||
OLED::drawAreaSwapped(0, 0, 96, 16, (uint8_t*) (logo_page + 4));
|
||||
OLED::refresh();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,71 +1,29 @@
|
||||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.3.1
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Implementation of functions defined in portable.h for the ARM CM3 port.
|
||||
@@ -144,10 +102,6 @@ debugger. */
|
||||
#define portTASK_RETURN_ADDRESS prvTaskExitError
|
||||
#endif
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*
|
||||
* Setup the timer to generate the tick interrupts. The implementation in this
|
||||
* file is weak to allow application writers to change the timer used to
|
||||
@@ -174,10 +128,14 @@ static void prvTaskExitError( void );
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/* Each task maintains its own interrupt status in the critical nesting
|
||||
variable. */
|
||||
static UBaseType_t uxCriticalNesting = 0xaaaaaaaa;
|
||||
|
||||
/*
|
||||
* The number of SysTick increments that make up one tick period.
|
||||
*/
|
||||
#if configUSE_TICKLESS_IDLE == 1
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t ulTimerCountsForOneTick = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
@@ -185,7 +143,7 @@ static void prvTaskExitError( void );
|
||||
* The maximum number of tick periods that can be suppressed is limited by the
|
||||
* 24 bit resolution of the SysTick timer.
|
||||
*/
|
||||
#if configUSE_TICKLESS_IDLE == 1
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t xMaximumPossibleSuppressedTicks = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
@@ -193,7 +151,7 @@ static void prvTaskExitError( void );
|
||||
* Compensate for the CPU cycles that pass while the SysTick is stopped (low
|
||||
* power functionality only.
|
||||
*/
|
||||
#if configUSE_TICKLESS_IDLE == 1
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
static uint32_t ulStoppedTimerCompensation = 0;
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
@@ -202,7 +160,7 @@ static void prvTaskExitError( void );
|
||||
* FreeRTOS API functions are not called from interrupts that have been assigned
|
||||
* a priority above configMAX_SYSCALL_INTERRUPT_PRIORITY.
|
||||
*/
|
||||
#if ( configASSERT_DEFINED == 1 )
|
||||
#if( configASSERT_DEFINED == 1 )
|
||||
static uint8_t ucMaxSysCallPriority = 0;
|
||||
static uint32_t ulMaxPRIGROUPValue = 0;
|
||||
static const volatile uint8_t * const pcInterruptPriorityRegisters = ( const volatile uint8_t * const ) portNVIC_IP_REGISTERS_OFFSET_16;
|
||||
@@ -233,6 +191,8 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px
|
||||
|
||||
static void prvTaskExitError( void )
|
||||
{
|
||||
volatile uint32_t ulDummy = 0UL;
|
||||
|
||||
/* A function that implements a task must not exit or attempt to return to
|
||||
its caller as there is nothing to return to. If a task wants to exit it
|
||||
should instead call vTaskDelete( NULL ).
|
||||
@@ -241,7 +201,16 @@ static void prvTaskExitError( void )
|
||||
defined, then stop here so application writers can catch the error. */
|
||||
configASSERT( uxCriticalNesting == ~0UL );
|
||||
portDISABLE_INTERRUPTS();
|
||||
for( ;; );
|
||||
while( ulDummy == 0 )
|
||||
{
|
||||
/* This file calls prvTaskExitError() after the scheduler has been
|
||||
started to remove a compiler warning about the function being defined
|
||||
but never called. ulDummy is used purely to quieten other warnings
|
||||
about code appearing after this function is called - making ulDummy
|
||||
volatile makes the compiler think the function could return and
|
||||
therefore not output an 'unreachable code' warning for code that appears
|
||||
after it. */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
@@ -324,6 +293,24 @@ BaseType_t xPortStartScheduler( void )
|
||||
ucMaxPriorityValue <<= ( uint8_t ) 0x01;
|
||||
}
|
||||
|
||||
#ifdef __NVIC_PRIO_BITS
|
||||
{
|
||||
/* Check the CMSIS configuration that defines the number of
|
||||
priority bits matches the number of priority bits actually queried
|
||||
from the hardware. */
|
||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == __NVIC_PRIO_BITS );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef configPRIO_BITS
|
||||
{
|
||||
/* Check the FreeRTOS configuration that defines the number of
|
||||
priority bits matches the number of priority bits actually queried
|
||||
from the hardware. */
|
||||
configASSERT( ( portMAX_PRIGROUP_BITS - ulMaxPRIGROUPValue ) == configPRIO_BITS );
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Shift the priority group value back to its position within the AIRCR
|
||||
register. */
|
||||
ulMaxPRIGROUPValue <<= portPRIGROUP_SHIFT;
|
||||
@@ -352,7 +339,10 @@ BaseType_t xPortStartScheduler( void )
|
||||
/* Should never get here as the tasks will now be executing! Call the task
|
||||
exit error function to prevent compiler warnings about a static function
|
||||
not being called in the case that the application writer overrides this
|
||||
functionality by defining configTASK_RETURN_ADDRESS. */
|
||||
functionality by defining configTASK_RETURN_ADDRESS. Call
|
||||
vTaskSwitchContext() so link time optimisation does not remove the
|
||||
symbol. */
|
||||
vTaskSwitchContext();
|
||||
prvTaskExitError();
|
||||
|
||||
/* Should not get here! */
|
||||
@@ -418,7 +408,7 @@ void xPortPendSVHandler( void )
|
||||
" mov r0, #0 \n"
|
||||
" msr basepri, r0 \n"
|
||||
" ldmia sp!, {r3, r14} \n"
|
||||
" \n" /* Restore the context, including the critical nesting count. */
|
||||
" \n" /* Restore the context, including the critical nesting count. */
|
||||
" ldr r1, [r3] \n"
|
||||
" ldr r0, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. */
|
||||
" ldmia r0!, {r4-r11} \n" /* Pop the registers. */
|
||||
@@ -453,11 +443,11 @@ void xPortSysTickHandler( void )
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#if configUSE_TICKLESS_IDLE == 1
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
|
||||
__attribute__((weak)) void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
|
||||
{
|
||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements, ulSysTickCTRL;
|
||||
uint32_t ulReloadValue, ulCompleteTickPeriods, ulCompletedSysTickDecrements;
|
||||
TickType_t xModifiableIdleTime;
|
||||
|
||||
/* Make sure the SysTick reload value does not overflow the counter. */
|
||||
@@ -483,7 +473,7 @@ void xPortSysTickHandler( void )
|
||||
|
||||
/* Enter a critical section but don't use the taskENTER_CRITICAL()
|
||||
method as that will mask interrupts that should exit sleep mode. */
|
||||
__asm volatile( "cpsid i" );
|
||||
__asm volatile( "cpsid i" ::: "memory" );
|
||||
__asm volatile( "dsb" );
|
||||
__asm volatile( "isb" );
|
||||
|
||||
@@ -504,7 +494,7 @@ void xPortSysTickHandler( void )
|
||||
|
||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||
above. */
|
||||
__asm volatile( "cpsie i" );
|
||||
__asm volatile( "cpsie i" ::: "memory" );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -524,32 +514,50 @@ void xPortSysTickHandler( void )
|
||||
should not be executed again. However, the original expected idle
|
||||
time variable must remain unmodified, so a copy is taken. */
|
||||
xModifiableIdleTime = xExpectedIdleTime;
|
||||
configPRE_SLEEP_PROCESSING( &xModifiableIdleTime );
|
||||
configPRE_SLEEP_PROCESSING( xModifiableIdleTime );
|
||||
if( xModifiableIdleTime > 0 )
|
||||
{
|
||||
__asm volatile( "dsb" );
|
||||
__asm volatile( "dsb" ::: "memory" );
|
||||
__asm volatile( "wfi" );
|
||||
__asm volatile( "isb" );
|
||||
}
|
||||
configPOST_SLEEP_PROCESSING( &xExpectedIdleTime );
|
||||
configPOST_SLEEP_PROCESSING( xExpectedIdleTime );
|
||||
|
||||
/* Stop SysTick. Again, the time the SysTick is stopped for is
|
||||
accounted for as best it can be, but using the tickless mode will
|
||||
inevitably result in some tiny drift of the time maintained by the
|
||||
kernel with respect to calendar time. */
|
||||
ulSysTickCTRL = portNVIC_SYSTICK_CTRL_REG;
|
||||
portNVIC_SYSTICK_CTRL_REG = ( ulSysTickCTRL & ~portNVIC_SYSTICK_ENABLE_BIT );
|
||||
/* Re-enable interrupts to allow the interrupt that brought the MCU
|
||||
out of sleep mode to execute immediately. see comments above
|
||||
__disable_interrupt() call above. */
|
||||
__asm volatile( "cpsie i" ::: "memory" );
|
||||
__asm volatile( "dsb" );
|
||||
__asm volatile( "isb" );
|
||||
|
||||
/* Re-enable interrupts - see comments above the cpsid instruction()
|
||||
above. */
|
||||
__asm volatile( "cpsie i" );
|
||||
/* Disable interrupts again because the clock is about to be stopped
|
||||
and interrupts that execute while the clock is stopped will increase
|
||||
any slippage between the time maintained by the RTOS and calendar
|
||||
time. */
|
||||
__asm volatile( "cpsid i" ::: "memory" );
|
||||
__asm volatile( "dsb" );
|
||||
__asm volatile( "isb" );
|
||||
|
||||
if( ( ulSysTickCTRL & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||
/* Disable the SysTick clock without reading the
|
||||
portNVIC_SYSTICK_CTRL_REG register to ensure the
|
||||
portNVIC_SYSTICK_COUNT_FLAG_BIT is not cleared if it is set. Again,
|
||||
the time the SysTick is stopped for is accounted for as best it can
|
||||
be, but using the tickless mode will inevitably result in some tiny
|
||||
drift of the time maintained by the kernel with respect to calendar
|
||||
time*/
|
||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT );
|
||||
|
||||
/* Determine if the SysTick clock has already counted to zero and
|
||||
been set back to the current reload value (the reload back being
|
||||
correct for the entire expected idle time) or if the SysTick is yet
|
||||
to count to zero (in which case an interrupt other than the SysTick
|
||||
must have brought the system out of sleep mode). */
|
||||
if( ( portNVIC_SYSTICK_CTRL_REG & portNVIC_SYSTICK_COUNT_FLAG_BIT ) != 0 )
|
||||
{
|
||||
uint32_t ulCalculatedLoadValue;
|
||||
|
||||
/* The tick interrupt has already executed, and the SysTick
|
||||
count reloaded with ulReloadValue. Reset the
|
||||
/* The tick interrupt is already pending, and the SysTick count
|
||||
reloaded with ulReloadValue. Reset the
|
||||
portNVIC_SYSTICK_LOAD_REG with whatever remains of this tick
|
||||
period. */
|
||||
ulCalculatedLoadValue = ( ulTimerCountsForOneTick - 1UL ) - ( ulReloadValue - portNVIC_SYSTICK_CURRENT_VALUE_REG );
|
||||
@@ -564,11 +572,9 @@ void xPortSysTickHandler( void )
|
||||
|
||||
portNVIC_SYSTICK_LOAD_REG = ulCalculatedLoadValue;
|
||||
|
||||
/* The tick interrupt handler will already have pended the tick
|
||||
processing in the kernel. As the pending tick will be
|
||||
processed as soon as this function exits, the tick value
|
||||
maintained by the tick is stepped forward by one less than the
|
||||
time spent waiting. */
|
||||
/* As the pending tick will be processed as soon as this
|
||||
function exits, the tick value maintained by the tick is stepped
|
||||
forward by one less than the time spent waiting. */
|
||||
ulCompleteTickPeriods = xExpectedIdleTime - 1UL;
|
||||
}
|
||||
else
|
||||
@@ -590,21 +596,18 @@ void xPortSysTickHandler( void )
|
||||
|
||||
/* Restart SysTick so it runs from portNVIC_SYSTICK_LOAD_REG
|
||||
again, then set portNVIC_SYSTICK_LOAD_REG back to its standard
|
||||
value. The critical section is used to ensure the tick interrupt
|
||||
can only execute once in the case that the reload register is near
|
||||
zero. */
|
||||
value. */
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||
portENTER_CRITICAL();
|
||||
{
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
vTaskStepTick( ulCompleteTickPeriods );
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
}
|
||||
portEXIT_CRITICAL();
|
||||
portNVIC_SYSTICK_CTRL_REG |= portNVIC_SYSTICK_ENABLE_BIT;
|
||||
vTaskStepTick( ulCompleteTickPeriods );
|
||||
portNVIC_SYSTICK_LOAD_REG = ulTimerCountsForOneTick - 1UL;
|
||||
|
||||
/* Exit with interrupts enabled. */
|
||||
__asm volatile( "cpsie i" ::: "memory" );
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if configUSE_TICKLESS_IDLE */
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
@@ -614,7 +617,7 @@ void xPortSysTickHandler( void )
|
||||
__attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||
{
|
||||
/* Calculate the constants required to configure the tick interrupt. */
|
||||
#if configUSE_TICKLESS_IDLE == 1
|
||||
#if( configUSE_TICKLESS_IDLE == 1 )
|
||||
{
|
||||
ulTimerCountsForOneTick = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ );
|
||||
xMaximumPossibleSuppressedTicks = portMAX_24_BIT_NUMBER / ulTimerCountsForOneTick;
|
||||
@@ -622,6 +625,10 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||
}
|
||||
#endif /* configUSE_TICKLESS_IDLE */
|
||||
|
||||
/* Stop and clear the SysTick. */
|
||||
portNVIC_SYSTICK_CTRL_REG = 0UL;
|
||||
portNVIC_SYSTICK_CURRENT_VALUE_REG = 0UL;
|
||||
|
||||
/* Configure SysTick to interrupt at the requested rate. */
|
||||
portNVIC_SYSTICK_LOAD_REG = ( configSYSTICK_CLOCK_HZ / configTICK_RATE_HZ ) - 1UL;
|
||||
portNVIC_SYSTICK_CTRL_REG = ( portNVIC_SYSTICK_CLK_BIT | portNVIC_SYSTICK_INT_BIT | portNVIC_SYSTICK_ENABLE_BIT );
|
||||
@@ -636,7 +643,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||
uint8_t ucCurrentPriority;
|
||||
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
|
||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
||||
|
||||
/* Is the interrupt number a user defined interrupt? */
|
||||
if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
|
||||
@@ -682,7 +689,7 @@ __attribute__(( weak )) void vPortSetupTimerInterrupt( void )
|
||||
devices by calling NVIC_SetPriorityGrouping( 0 ); before starting the
|
||||
scheduler. Note however that some vendor specific peripheral libraries
|
||||
assume a non-zero priority group setting, in which cases using a value
|
||||
of zero will result in unpredicable behaviour. */
|
||||
of zero will result in unpredictable behaviour. */
|
||||
configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
|
||||
}
|
||||
|
||||
|
||||
@@ -1,71 +1,29 @@
|
||||
/*
|
||||
FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
|
||||
|
||||
***************************************************************************
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
***************************************************************************
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available on the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that is more than just the market leader, it *
|
||||
* is the industry's de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly while simultaneously helping *
|
||||
* to support the FreeRTOS project by purchasing a FreeRTOS *
|
||||
* tutorial book, reference manual, or both: *
|
||||
* http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
|
||||
the FAQ page "My application does not run, what could be wrong?". Have you
|
||||
defined configASSERT()?
|
||||
|
||||
http://www.FreeRTOS.org/support - In return for receiving this top quality
|
||||
embedded software for free we request you assist our global community by
|
||||
participating in the support forum.
|
||||
|
||||
http://www.FreeRTOS.org/training - Investing in training allows your team to
|
||||
be as productive as possible as early as possible. Now you can receive
|
||||
FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
|
||||
Ltd, and the world's leading authority on the world's leading RTOS.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
|
||||
Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
|
||||
Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and commercial middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
* FreeRTOS Kernel V10.3.1
|
||||
* Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
* this software and associated documentation files (the "Software"), to deal in
|
||||
* the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
* the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
* subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* http://www.FreeRTOS.org
|
||||
* http://aws.amazon.com/freertos
|
||||
*
|
||||
* 1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PORTMACRO_H
|
||||
@@ -125,7 +83,7 @@ typedef unsigned long UBaseType_t;
|
||||
\
|
||||
/* Barriers are normally not required but do ensure the code is completely \
|
||||
within the specified behaviour for the architecture. */ \
|
||||
__asm volatile( "dsb" ); \
|
||||
__asm volatile( "dsb" ::: "memory" ); \
|
||||
__asm volatile( "isb" ); \
|
||||
}
|
||||
|
||||
@@ -173,7 +131,7 @@ not necessary for to use this port. They are defined so the common demo files
|
||||
{
|
||||
uint8_t ucReturn;
|
||||
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) );
|
||||
__asm volatile ( "clz %0, %1" : "=r" ( ucReturn ) : "r" ( ulBitmap ) : "memory" );
|
||||
return ucReturn;
|
||||
}
|
||||
|
||||
@@ -208,13 +166,15 @@ not necessary for to use this port. They are defined so the common demo files
|
||||
#define portFORCE_INLINE inline __attribute__(( always_inline))
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
portFORCE_INLINE static BaseType_t xPortIsInsideInterrupt( void )
|
||||
{
|
||||
uint32_t ulCurrentInterrupt;
|
||||
BaseType_t xReturn;
|
||||
|
||||
/* Obtain the number of the currently executing interrupt. */
|
||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) );
|
||||
__asm volatile( "mrs %0, ipsr" : "=r"( ulCurrentInterrupt ) :: "memory" );
|
||||
|
||||
if( ulCurrentInterrupt == 0 )
|
||||
{
|
||||
@@ -236,11 +196,11 @@ uint32_t ulNewBASEPRI;
|
||||
|
||||
__asm volatile
|
||||
(
|
||||
" mov %0, %1 \n" \
|
||||
" mov %0, %1 \n" \
|
||||
" msr basepri, %0 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
:"=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -253,11 +213,11 @@ uint32_t ulOriginalBASEPRI, ulNewBASEPRI;
|
||||
__asm volatile
|
||||
(
|
||||
" mrs %0, basepri \n" \
|
||||
" mov %1, %2 \n" \
|
||||
" mov %1, %2 \n" \
|
||||
" msr basepri, %1 \n" \
|
||||
" isb \n" \
|
||||
" dsb \n" \
|
||||
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY )
|
||||
:"=r" (ulOriginalBASEPRI), "=r" (ulNewBASEPRI) : "i" ( configMAX_SYSCALL_INTERRUPT_PRIORITY ) : "memory"
|
||||
);
|
||||
|
||||
/* This return will not be reached but is necessary to prevent compiler
|
||||
@@ -270,11 +230,12 @@ portFORCE_INLINE static void vPortSetBASEPRI( uint32_t ulNewMaskValue )
|
||||
{
|
||||
__asm volatile
|
||||
(
|
||||
" msr basepri, %0 " :: "r" ( ulNewMaskValue )
|
||||
" msr basepri, %0 " :: "r" ( ulNewMaskValue ) : "memory"
|
||||
);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -9,11 +9,13 @@
|
||||
#include "task.h"
|
||||
#include "I2C_Wrapper.hpp"
|
||||
#include "fusbpd.h"
|
||||
|
||||
// Initialisation to be performed with scheduler active
|
||||
void postRToSInit() {
|
||||
// Any after RTos setup
|
||||
FRToSI2C::FRToSInit();
|
||||
#ifdef POW_PD
|
||||
//Spawn all of the USB-C processors
|
||||
fusb302_start_processing();
|
||||
if (usb_pd_detect() == true) {
|
||||
//Spawn all of the USB-C processors
|
||||
fusb302_start_processing();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -17,13 +17,9 @@ void preRToSInit() {
|
||||
*/
|
||||
HAL_Init();
|
||||
Setup_HAL(); // Setup all the HAL objects
|
||||
FRToSI2C::init();
|
||||
HAL_Delay(50);
|
||||
HAL_GPIO_WritePin(OLED_RESET_GPIO_Port, OLED_RESET_Pin, GPIO_PIN_SET);
|
||||
HAL_Delay(50);
|
||||
#ifdef I2C_SOFT
|
||||
I2CBB::init();
|
||||
|
||||
#endif
|
||||
|
||||
/* Init the IPC objects */
|
||||
FRToSI2C::FRToSInit();
|
||||
}
|
||||
|
||||
@@ -11,16 +11,13 @@
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/* #define DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
//#define LOCAL_BUILD
|
||||
#ifndef LOCAL_BUILD
|
||||
|
||||
#ifndef VECT_TAB_OFFSET
|
||||
#define VECT_TAB_OFFSET 0x00004000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#else
|
||||
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
|
||||
This value must be a multiple of 0x200. */
|
||||
#warning LOCAL_BUILD SETUP
|
||||
#endif
|
||||
//We offset this by 0x4000 to because of the bootloader
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Clock Definitions
|
||||
*******************************************************************************/
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
/*
|
||||
* PD Buddy Firmware Library - USB Power Delivery for everyone
|
||||
* Copyright 2017-2018 Clayton G. Hobbs
|
||||
*
|
||||
* 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 "hard_reset.h"
|
||||
#include "fusbpd.h"
|
||||
#include <pd.h>
|
||||
#include "policy_engine.h"
|
||||
#include "protocol_rx.h"
|
||||
#include "protocol_tx.h"
|
||||
#include "fusb302b.h"
|
||||
|
||||
osThreadId ResetHandler::TaskHandle = NULL;
|
||||
uint32_t ResetHandler::TaskBuffer[ResetHandler::TaskStackSize];
|
||||
osStaticThreadDef_t ResetHandler::TaskControlBlock;
|
||||
|
||||
/*
|
||||
* PRL_HR_Reset_Layer state
|
||||
*/
|
||||
ResetHandler::hardrst_state ResetHandler::hardrst_reset_layer() {
|
||||
/* First, wait for the signal to run a hard reset. */
|
||||
eventmask_t evt = waitForEvent(
|
||||
PDB_EVT_HARDRST_RESET | PDB_EVT_HARDRST_I_HARDRST);
|
||||
if (evt & (PDB_EVT_HARDRST_RESET | PDB_EVT_HARDRST_I_HARDRST)) {
|
||||
/* Reset the Protocol RX machine */
|
||||
ProtocolReceive::notify( PDB_EVT_PRLRX_RESET);
|
||||
taskYIELD();
|
||||
/* Reset the Protocol TX machine */
|
||||
ProtocolTransmit::notify(
|
||||
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_RESET);
|
||||
taskYIELD();
|
||||
/* Continue the process based on what event started the reset. */
|
||||
if (evt & PDB_EVT_HARDRST_RESET) {
|
||||
/* Policy Engine started the reset. */
|
||||
return PRLHRRequestHardReset;
|
||||
} else {
|
||||
/* PHY started the reset */
|
||||
return PRLHRIndicateHardReset;
|
||||
}
|
||||
} else {
|
||||
return PRLHRResetLayer;
|
||||
}
|
||||
}
|
||||
|
||||
ResetHandler::hardrst_state ResetHandler::hardrst_indicate_hard_reset() {
|
||||
/* Tell the PE that we're doing a hard reset */
|
||||
PolicyEngine::notify( PDB_EVT_PE_RESET);
|
||||
|
||||
return PRLHRWaitPE;
|
||||
}
|
||||
|
||||
ResetHandler::hardrst_state ResetHandler::hardrst_request_hard_reset() {
|
||||
/* Tell the PHY to send a hard reset */
|
||||
fusb_send_hardrst();
|
||||
|
||||
return PRLHRWaitPHY;
|
||||
}
|
||||
|
||||
ResetHandler::hardrst_state ResetHandler::hardrst_wait_phy() {
|
||||
/* Wait for the PHY to tell us that it's done sending the hard reset */
|
||||
waitForEvent(PDB_EVT_HARDRST_I_HARDSENT, PD_T_HARD_RESET_COMPLETE);
|
||||
|
||||
/* Move on no matter what made us stop waiting. */
|
||||
return PRLHRHardResetRequested;
|
||||
}
|
||||
|
||||
ResetHandler::hardrst_state ResetHandler::hardrst_hard_reset_requested() {
|
||||
/* Tell the PE that the hard reset was sent */
|
||||
PolicyEngine::notify( PDB_EVT_PE_HARD_SENT);
|
||||
|
||||
return PRLHRWaitPE;
|
||||
}
|
||||
|
||||
ResetHandler::hardrst_state ResetHandler::hardrst_wait_pe() {
|
||||
/* Wait for the PE to tell us that it's done */
|
||||
waitForEvent(PDB_EVT_HARDRST_DONE);
|
||||
|
||||
return PRLHRComplete;
|
||||
}
|
||||
|
||||
ResetHandler::hardrst_state ResetHandler::hardrst_complete() {
|
||||
/* I'm not aware of anything we have to tell the FUSB302B, so just finish
|
||||
* the reset routine. */
|
||||
return PRLHRResetLayer;
|
||||
}
|
||||
|
||||
void ResetHandler::init() {
|
||||
osThreadStaticDef(rstHand, Thread, PDB_PRIO_PRL, 0, TaskStackSize,
|
||||
TaskBuffer, &TaskControlBlock);
|
||||
TaskHandle = osThreadCreate(osThread(rstHand), NULL);
|
||||
}
|
||||
|
||||
void ResetHandler::notify(uint32_t notification) {
|
||||
if (TaskHandle != NULL) {
|
||||
xTaskNotify(TaskHandle, notification, eNotifyAction::eSetBits);
|
||||
}
|
||||
}
|
||||
|
||||
void ResetHandler::Thread(const void *arg) {
|
||||
(void) arg;
|
||||
ResetHandler::hardrst_state state = PRLHRResetLayer;
|
||||
|
||||
while (true) {
|
||||
switch (state) {
|
||||
case PRLHRResetLayer:
|
||||
state = hardrst_reset_layer();
|
||||
break;
|
||||
case PRLHRIndicateHardReset:
|
||||
state = hardrst_indicate_hard_reset();
|
||||
break;
|
||||
case PRLHRRequestHardReset:
|
||||
state = hardrst_request_hard_reset();
|
||||
break;
|
||||
case PRLHRWaitPHY:
|
||||
state = hardrst_wait_phy();
|
||||
break;
|
||||
case PRLHRHardResetRequested:
|
||||
state = hardrst_hard_reset_requested();
|
||||
break;
|
||||
case PRLHRWaitPE:
|
||||
state = hardrst_wait_pe();
|
||||
break;
|
||||
case PRLHRComplete:
|
||||
state = hardrst_complete();
|
||||
break;
|
||||
default:
|
||||
/* This is an error. It really shouldn't happen. We might
|
||||
* want to handle it anyway, though. */
|
||||
state = PRLHRResetLayer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ResetHandler::waitForEvent(uint32_t mask, uint32_t ticksToWait) {
|
||||
uint32_t pulNotificationValue;
|
||||
xTaskNotifyWait(0x00, mask, &pulNotificationValue, ticksToWait);
|
||||
return pulNotificationValue;
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* PD Buddy Firmware Library - USB Power Delivery for everyone
|
||||
* Copyright 2017-2018 Clayton G. Hobbs
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef PDB_HARD_RESET_H
|
||||
#define PDB_HARD_RESET_H
|
||||
|
||||
#include <pd.h>
|
||||
|
||||
/* Events for the Hard Reset thread */
|
||||
#define PDB_EVT_HARDRST_RESET EVENT_MASK(0)
|
||||
#define PDB_EVT_HARDRST_I_HARDRST EVENT_MASK(1)
|
||||
#define PDB_EVT_HARDRST_I_HARDSENT EVENT_MASK(2)
|
||||
#define PDB_EVT_HARDRST_DONE EVENT_MASK(3)
|
||||
|
||||
class ResetHandler {
|
||||
public:
|
||||
static void init();
|
||||
static void notify(uint32_t notification);
|
||||
private:
|
||||
static void Thread(const void *arg);
|
||||
static osThreadId TaskHandle;
|
||||
static const size_t TaskStackSize = 1536 / 2;
|
||||
static uint32_t TaskBuffer[TaskStackSize];
|
||||
static osStaticThreadDef_t TaskControlBlock;
|
||||
static uint32_t waitForEvent(uint32_t mask, uint32_t ticksToWait =
|
||||
portMAX_DELAY);
|
||||
|
||||
/*
|
||||
* Hard Reset machine states
|
||||
*/
|
||||
enum hardrst_state {
|
||||
PRLHRResetLayer,
|
||||
PRLHRIndicateHardReset,
|
||||
PRLHRRequestHardReset,
|
||||
PRLHRWaitPHY,
|
||||
PRLHRHardResetRequested,
|
||||
PRLHRWaitPE,
|
||||
PRLHRComplete
|
||||
};
|
||||
static hardrst_state hardrst_reset_layer();
|
||||
static hardrst_state hardrst_indicate_hard_reset();
|
||||
static hardrst_state hardrst_request_hard_reset();
|
||||
static hardrst_state hardrst_wait_phy();
|
||||
static hardrst_state hardrst_hard_reset_requested();
|
||||
static hardrst_state hardrst_wait_pe();
|
||||
static hardrst_state hardrst_complete();
|
||||
};
|
||||
|
||||
#endif /* PDB_HARD_RESET_H */
|
||||
@@ -99,12 +99,18 @@ OUTPUT_DIR=Objects
|
||||
|
||||
# code optimisation ------------------------------------------------------------
|
||||
OPTIM_AS= -Wall
|
||||
OPTIM=-Os -flto -ffat-lto-objects -finline-small-functions -findirect-inlining -fdiagnostics-color -ffunction-sections -fdata-sections
|
||||
OPTIM=-Os -flto -finline-small-functions -findirect-inlining -fdiagnostics-color -ffunction-sections -fdata-sections
|
||||
|
||||
flash_size=64k
|
||||
bootldr_size=0x4000
|
||||
|
||||
# global defines ---------------------------------------------------------------
|
||||
GLOBAL_DEFINES += -D LANG_$(lang) -D LANG -D MODEL_$(model) $(DEV_GLOBAL_DEFS)
|
||||
|
||||
ifdef swd_enable
|
||||
GLOBAL_DEFINES += -DSWD_ENABLE
|
||||
endif
|
||||
|
||||
# Enable debug code generation
|
||||
DEBUG=-g3
|
||||
|
||||
@@ -162,6 +168,8 @@ LINKER_FLAGS=-Wl,--gc-sections \
|
||||
$(CPUFLAGS) \
|
||||
-lm -Og -flto -Wl,--undefined=vTaskSwitchContext \
|
||||
-T$(LDSCRIPT) \
|
||||
-Wl,--defsym=__FLASH_SIZE__=$(flash_size) \
|
||||
-Wl,--defsym=__BOOTLDR_SIZE__=$(bootldr_size) \
|
||||
--specs=nano.specs \
|
||||
$(DEV_LDFLAGS)
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ AVAILABLE_MODELS=("TS100" "TS80" "TS80P" "Pinecil")
|
||||
BUILD_MODELS=()
|
||||
|
||||
usage() {
|
||||
echo "Usage : $(basename "$0") [-l <LANG_CODE>] [-m <TS100|TS80>] [-h]
|
||||
echo "Usage : $(basename "$0") [-l <LANG_CODE>] [-m <TS100|TS80|TS80P>] [-h]
|
||||
|
||||
Parameters :
|
||||
-l LANG_CODE : Force a specific language (E.g. : EN, FR, NL_BE, ...)
|
||||
|
||||
@@ -50,10 +50,10 @@
|
||||
/**
|
||||
* Temp change settings
|
||||
*/
|
||||
#define TEMP_CHANGE_SHORT_STEP 1 // Default temp change short step +1
|
||||
#define TEMP_CHANGE_LONG_STEP 10 // Default temp change long step +10
|
||||
#define TEMP_CHANGE_SHORT_STEP_MAX 50 // Temp change short step MAX value
|
||||
#define TEMP_CHANGE_LONG_STEP_MAX 100 // Temp change long step MAX value
|
||||
#define TEMP_CHANGE_SHORT_STEP 1 // Default temp change short step +1
|
||||
#define TEMP_CHANGE_LONG_STEP 10 // Default temp change long step +10
|
||||
#define TEMP_CHANGE_SHORT_STEP_MAX 50 // Temp change short step MAX value
|
||||
#define TEMP_CHANGE_LONG_STEP_MAX 90 // Temp change long step MAX value
|
||||
|
||||
/* Power pulse for keeping power banks awake*/
|
||||
#define POWER_PULSE_INCREMENT 1
|
||||
@@ -77,10 +77,9 @@
|
||||
#define DETAILED_SOLDERING 0 // 0: Disable 1: Enable - Default 0
|
||||
#define DETAILED_IDLE 0 // 0: Disable 1: Enable - Default 0
|
||||
|
||||
#define CUT_OUT_SETTING 0 // default to no cut-off voltage (or 18W for TS80)
|
||||
#define TEMPERATURE_INF 0 // default to 0
|
||||
#define DESCRIPTION_SCROLL_SPEED 0 // 0: Slow 1: Fast - default to slow
|
||||
#define POWER_LIMIT_ENABLE 0 // 0: Disable 1: Enable - Default disabled power limit
|
||||
#define CUT_OUT_SETTING 0 // default to no cut-off voltage (or 18W for TS80)
|
||||
#define TEMPERATURE_INF 0 // default to 0
|
||||
#define DESCRIPTION_SCROLL_SPEED 0 // 0: Slow 1: Fast - default to slow
|
||||
|
||||
#define TIP_GAIN 210 // 21 uV/C * 10, uV per deg C constant of the tip, Tip uV * 10 / coeff = tip temp
|
||||
|
||||
|
||||
@@ -9,17 +9,15 @@ _estack = 0x20005000; /* end of RAM */
|
||||
_Min_Heap_Size = 0x300; /* required amount of heap */
|
||||
_Min_Stack_Size = 1024; /* required amount of stack */
|
||||
|
||||
__APP_BASE_ADDRESS__ = 0x08000000 + __BOOTLDR_SIZE__;
|
||||
__ROM_REGION_LENGTH__ = __FLASH_SIZE__ - __BOOTLDR_SIZE__;
|
||||
__FLASH_END_ADDR__ = __APP_BASE_ADDRESS__ + __ROM_REGION_LENGTH__;
|
||||
|
||||
/* Memories definition */
|
||||
MEMORY
|
||||
{
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
/* LOCAL_BUILD*/
|
||||
/*ROM (rx) : ORIGIN = 0x08000000, LENGTH = 48K*/
|
||||
/* production*/
|
||||
ROM (rx) : ORIGIN = 0x08004000, LENGTH = 46K
|
||||
|
||||
|
||||
|
||||
ROM (rx) : ORIGIN = __APP_BASE_ADDRESS__, LENGTH = __ROM_REGION_LENGTH__
|
||||
}
|
||||
/* ROM is normally 48K after the bootloader, however we allocate the last page for settings, and the second last one for display boot logo*/
|
||||
|
||||
@@ -118,11 +116,22 @@ SECTIONS
|
||||
_edata = .; /* define a global symbol at data end */
|
||||
} >RAM AT> ROM
|
||||
|
||||
|
||||
/* Uninitialized data section into RAM memory */
|
||||
. = ALIGN(4);
|
||||
.logo_page (NOLOAD) :
|
||||
{
|
||||
. = ABSOLUTE(__FLASH_END_ADDR__ - 2048);
|
||||
KEEP (*(.logo_page*))
|
||||
} > ROM
|
||||
|
||||
.settings_page (NOLOAD) :
|
||||
{
|
||||
. = ABSOLUTE(__FLASH_END_ADDR__ - 1024);
|
||||
KEEP (*(.settings_page*))
|
||||
} > ROM
|
||||
|
||||
.bss :
|
||||
{
|
||||
/* Uninitialized data section into RAM memory */
|
||||
. = ALIGN(4);
|
||||
/* This is used by the startup in order to initialize the .bss secion */
|
||||
_sbss = .; /* define a global symbol at bss start */
|
||||
__bss_start__ = _sbss;
|
||||
@@ -157,4 +166,4 @@ SECTIONS
|
||||
}
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,4 +4,4 @@
|
||||
* i.e.: BUILD_VERSION = 'Rel. v2.08' --> Will generated to: 'v2.08.1a2b3c4'
|
||||
*/
|
||||
|
||||
#define BUILD_VERSION "v2.10"
|
||||
#define BUILD_VERSION "v2.12"
|
||||
|
||||
Reference in New Issue
Block a user