1
0
forked from me/IronOS

Reset some encodings

This commit is contained in:
Ben V. Brown
2020-12-11 19:11:23 +11:00
parent 120a0502d6
commit b63f02d033
76 changed files with 1549 additions and 1071 deletions

0
workspace/TS100/Core/BSP/BSP.h Normal file → Executable file
View File

0
workspace/TS100/Core/BSP/BSP_Common.c Normal file → Executable file
View File

0
workspace/TS100/Core/BSP/BSP_Flash.h Normal file → Executable file
View File

0
workspace/TS100/Core/BSP/BSP_PD.h Normal file → Executable file
View File

0
workspace/TS100/Core/BSP/BSP_Power.h Normal file → Executable file
View File

0
workspace/TS100/Core/BSP/BSP_QC.h Normal file → Executable file
View File

0
workspace/TS100/Core/BSP/Defines.h Normal file → Executable file
View File

View File

@@ -19,73 +19,71 @@
#define __RISCV_BITS_H__ #define __RISCV_BITS_H__
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#if __riscv_xlen == 64 #if __riscv_xlen == 64
#define SLL32 sllw # define SLL32 sllw
#define STORE sd # define STORE sd
#define LOAD ld # define LOAD ld
#define LWU lwu # define LWU lwu
#define LOG_REGBYTES 3 # define LOG_REGBYTES 3
#else #else
#define SLL32 sll # define SLL32 sll
#define STORE sw # define STORE sw
#define LOAD lw # define LOAD lw
#define LWU lw # define LWU lw
#define LOG_REGBYTES 2 # define LOG_REGBYTES 2
#endif /* __riscv_xlen */ #endif /* __riscv_xlen */
#define REGBYTES (1 << LOG_REGBYTES) #define REGBYTES (1 << LOG_REGBYTES)
#ifndef __riscv_flen
#define __riscv_flen 32
#endif
#if __riscv_flen == 64 #if __riscv_flen == 64
#define FPSTORE fsd # define FPSTORE fsd
#define FPLOAD fld # define FPLOAD fld
#define LOG_FPREGBYTES 3 # define LOG_FPREGBYTES 3
#else #else
#define FPSTORE fsw # define FPSTORE fsw
#define FPLOAD flw # define FPLOAD flw
#define LOG_FPREGBYTES 2 # define LOG_FPREGBYTES 2
#endif /* __riscv_flen */ #endif /* __riscv_flen */
#define FPREGBYTES (1 << LOG_FPREGBYTES) #define FPREGBYTES (1 << LOG_FPREGBYTES)
#define __rv_likely(x) __builtin_expect((x), 1) #define __rv_likely(x) __builtin_expect((x), 1)
#define __rv_unlikely(x) __builtin_expect((x), 0) #define __rv_unlikely(x) __builtin_expect((x), 0)
#define __RV_ROUNDUP(a, b) ((((a)-1) / (b) + 1) * (b)) #define __RV_ROUNDUP(a, b) ((((a)-1)/(b)+1)*(b))
#define __RV_ROUNDDOWN(a, b) ((a) / (b) * (b)) #define __RV_ROUNDDOWN(a, b) ((a)/(b)*(b))
#define __RV_MAX(a, b) ((a) > (b) ? (a) : (b)) #define __RV_MAX(a, b) ((a) > (b) ? (a) : (b))
#define __RV_MIN(a, b) ((a) < (b) ? (a) : (b)) #define __RV_MIN(a, b) ((a) < (b) ? (a) : (b))
#define __RV_CLAMP(a, lo, hi) MIN(MAX(a, lo), hi) #define __RV_CLAMP(a, lo, hi) MIN(MAX(a, lo), hi)
#define __RV_EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1))) #define __RV_EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
#define __RV_INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1)))) #define __RV_INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
#ifdef __ASSEMBLY__ #ifdef __ASSEMBLY__
#define _AC(X, Y) X #define _AC(X,Y) X
#define _AT(T, X) X #define _AT(T,X) X
#else #else
#define __AC(X, Y) (X##Y) #define __AC(X,Y) (X##Y)
#define _AC(X, Y) __AC(X, Y) #define _AC(X,Y) __AC(X,Y)
#define _AT(T, X) ((T)(X)) #define _AT(T,X) ((T)(X))
#endif /* __ASSEMBLY__ */ #endif /* __ASSEMBLY__ */
#define _UL(x) (_AC(x, UL)) #define _UL(x) (_AC(x, UL))
#define _ULL(x) (_AC(x, ULL)) #define _ULL(x) (_AC(x, ULL))
#define _BITUL(x) (_UL(1) << (x)) #define _BITUL(x) (_UL(1) << (x))
#define _BITULL(x) (_ULL(1) << (x)) #define _BITULL(x) (_ULL(1) << (x))
#define UL(x) (_UL(x)) #define UL(x) (_UL(x))
#define ULL(x) (_ULL(x)) #define ULL(x) (_ULL(x))
#define STR(x) XSTR(x) #define STR(x) XSTR(x)
#define XSTR(x) #x #define XSTR(x) #x
#define __STR(s) #s #define __STR(s) #s
#define STRINGIFY(s) __STR(s) #define STRINGIFY(s) __STR(s)
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -25,6 +25,7 @@
* 1 tab == 4 spaces! * 1 tab == 4 spaces!
*/ */
#ifndef PORTMACRO_H #ifndef PORTMACRO_H
#define PORTMACRO_H #define PORTMACRO_H
@@ -45,92 +46,90 @@ extern "C" {
*/ */
/* Type definitions. */ /* Type definitions. */
#define portCHAR char #define portCHAR char
#define portFLOAT float #define portFLOAT float
#define portDOUBLE double #define portDOUBLE double
#define portLONG long #define portLONG long
#define portSHORT short #define portSHORT short
#define portSTACK_TYPE unsigned long #define portSTACK_TYPE unsigned long
#define portBASE_TYPE long #define portBASE_TYPE long
#define portPOINTER_SIZE_TYPE unsigned long #define portPOINTER_SIZE_TYPE unsigned long
typedef portSTACK_TYPE StackType_t; typedef portSTACK_TYPE StackType_t;
typedef long BaseType_t; typedef long BaseType_t;
typedef unsigned long UBaseType_t; typedef unsigned long UBaseType_t;
#if (configUSE_16_BIT_TICKS == 1) #if( configUSE_16_BIT_TICKS == 1 )
typedef uint16_t TickType_t; typedef uint16_t TickType_t;
#define portMAX_DELAY (TickType_t)0xffff #define portMAX_DELAY ( TickType_t )0xffff
#else #else
/* RISC-V TIMER is 64-bit long */ /* RISC-V TIMER is 64-bit long */
typedef uint64_t TickType_t; typedef uint64_t TickType_t;
#define portMAX_DELAY (TickType_t)0xFFFFFFFFFFFFFFFFULL #define portMAX_DELAY ( TickType_t )0xFFFFFFFFFFFFFFFFULL
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Architecture specifics. */ /* Architecture specifics. */
#define portSTACK_GROWTH (-1) #define portSTACK_GROWTH ( -1 )
#define portTICK_PERIOD_MS ((TickType_t)1000 / configTICK_RATE_HZ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
#define portBYTE_ALIGNMENT 8 #define portBYTE_ALIGNMENT 8
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Scheduler utilities. */ /* Scheduler utilities. */
#define portYIELD() \ #define portYIELD() \
{ \ { \
/* Set a software interrupt(SWI) request to request a context switch. */ \ /* Set a software interrupt(SWI) request to request a context switch. */ \
SysTimer_SetSWIRQ(); \ SysTimer_SetSWIRQ(); \
/* Barriers are normally not required but do ensure the code is completely \ /* Barriers are normally not required but do ensure the code is completely \
within the specified behaviour for the architecture. */ \ within the specified behaviour for the architecture. */ \
__RWMB(); \ __RWMB(); \
} }
#define portEND_SWITCHING_ISR(xSwitchRequired) \ #define portEND_SWITCHING_ISR( xSwitchRequired ) if ( xSwitchRequired != pdFALSE ) portYIELD()
if (xSwitchRequired != pdFALSE) \ #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x )
portYIELD()
#define portYIELD_FROM_ISR(x) portEND_SWITCHING_ISR(x)
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Critical section management. */ /* Critical section management. */
extern void vPortEnterCritical(void); extern void vPortEnterCritical( void );
extern void vPortExitCritical(void); extern void vPortExitCritical( void );
#define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI() #define portSET_INTERRUPT_MASK_FROM_ISR() ulPortRaiseBASEPRI()
#define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x) #define portCLEAR_INTERRUPT_MASK_FROM_ISR(x) vPortSetBASEPRI(x)
#define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI() #define portDISABLE_INTERRUPTS() vPortRaiseBASEPRI()
#define portENABLE_INTERRUPTS() vPortSetBASEPRI(0) #define portENABLE_INTERRUPTS() vPortSetBASEPRI(0)
#define portENTER_CRITICAL() vPortEnterCritical() #define portENTER_CRITICAL() vPortEnterCritical()
#define portEXIT_CRITICAL() vPortExitCritical() #define portEXIT_CRITICAL() vPortExitCritical()
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Task function macros as described on the FreeRTOS.org WEB site. These are /* Task function macros as described on the FreeRTOS.org WEB site. These are
not necessary for to use this port. They are defined so the common demo files not necessary for to use this port. They are defined so the common demo files
(which build with all the ports) will build. */ (which build with all the ports) will build. */
#define portTASK_FUNCTION_PROTO(vFunction, pvParameters) void vFunction(void *pvParameters) #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
#define portTASK_FUNCTION(vFunction, pvParameters) void vFunction(void *pvParameters) #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Tickless idle/low power functionality. */ /* Tickless idle/low power functionality. */
#ifndef portSUPPRESS_TICKS_AND_SLEEP #ifndef portSUPPRESS_TICKS_AND_SLEEP
extern void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime); extern void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#define portSUPPRESS_TICKS_AND_SLEEP(xExpectedIdleTime) vPortSuppressTicksAndSleep(xExpectedIdleTime) #define portSUPPRESS_TICKS_AND_SLEEP( xExpectedIdleTime ) vPortSuppressTicksAndSleep( xExpectedIdleTime )
#endif #endif
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#ifdef configASSERT #ifdef configASSERT
extern void vPortValidateInterruptPriority(void); extern void vPortValidateInterruptPriority( void );
#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority() #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() vPortValidateInterruptPriority()
#endif #endif
/* portNOP() is not required by this port. */ /* portNOP() is not required by this port. */
#define portNOP() __NOP() #define portNOP() __NOP()
#define portINLINE __inline #define portINLINE __inline
#ifndef portFORCE_INLINE #ifndef portFORCE_INLINE
#define portFORCE_INLINE inline __attribute__((always_inline)) #define portFORCE_INLINE inline __attribute__(( always_inline))
#endif #endif
/* This variable should not be set in any of the FreeRTOS application /* This variable should not be set in any of the FreeRTOS application
@@ -138,14 +137,16 @@ extern void vPortValidateInterruptPriority(void);
extern uint8_t uxMaxSysCallMTH; extern uint8_t uxMaxSysCallMTH;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
portFORCE_INLINE static void vPortRaiseBASEPRI(void) { portFORCE_INLINE static void vPortRaiseBASEPRI( void )
{
ECLIC_SetMth(uxMaxSysCallMTH); ECLIC_SetMth(uxMaxSysCallMTH);
__RWMB(); __RWMB();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
portFORCE_INLINE static uint8_t ulPortRaiseBASEPRI(void) { portFORCE_INLINE static uint8_t ulPortRaiseBASEPRI( void )
{
uint8_t ulOriginalBASEPRI; uint8_t ulOriginalBASEPRI;
ulOriginalBASEPRI = ECLIC_GetMth(); ulOriginalBASEPRI = ECLIC_GetMth();
@@ -158,17 +159,18 @@ portFORCE_INLINE static uint8_t ulPortRaiseBASEPRI(void) {
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
portFORCE_INLINE static void vPortSetBASEPRI(uint8_t ulNewMaskValue) { portFORCE_INLINE static void vPortSetBASEPRI( uint8_t ulNewMaskValue )
{
ECLIC_SetMth(ulNewMaskValue); ECLIC_SetMth(ulNewMaskValue);
__RWMB(); __RWMB();
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#define portMEMORY_BARRIER() __asm volatile("" :: \ #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
: "memory")
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* PORTMACRO_H */ #endif /* PORTMACRO_H */

View File

@@ -0,0 +1,48 @@
/*!
\file gd32vf103v_eval.h
\brief definitions for GD32VF103V_EVAL's leds, keys and COM ports hardware resources
\version 2019-6-5, V1.0.0, demo for GD32VF103
*/
/*
Copyright (c) 2019, GigaDevice Semiconductor Inc.
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.
*/
#ifndef GD32VF103V_EVAL_H
#define GD32VF103V_EVAL_H
#ifdef cplusplus
extern "C" {
#endif
#include "nuclei_sdk_soc.h"
#ifdef cplusplus
}
#endif
#endif /* GD32VF103V_EVAL_H */

View File

@@ -0,0 +1,19 @@
// See LICENSE for license details.
#ifndef _NUCLEI_SDK_HAL_H
#define _NUCLEI_SDK_HAL_H
#ifdef __cplusplus
extern "C" {
#endif
#include "gd32vf103v_eval.h"
#ifndef NUCLEI_BANNER
#define NUCLEI_BANNER 0
#endif
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,284 @@
/*
* Copyright (c) 2019 Nuclei Limited. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* 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
*
* 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.
*/
/******************************************************************************
* @file gcc_Device.ld
* @brief GNU Linker Script for gd32vf103 based device
* @version V1.0.0
* @date 17. Dec 2019
******************************************************************************/
/*********** Use Configuration Wizard in Context Menu *************************/
OUTPUT_ARCH( "riscv" )
/********************* Flash Configuration ************************************
* <h> Flash Configuration
* <o0> Flash Base Address <0x0-0xFFFFFFFF:8>
* <o1> Flash Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__ROM_BASE = 0x08000000;
__ROM_SIZE = 0x00020000;
/*--------------------- ILM RAM Configuration ---------------------------
* <h> ILM RAM Configuration
* <o0> ILM RAM Base Address <0x0-0xFFFFFFFF:8>
* <o1> ILM RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__ILM_RAM_BASE = 0x80000000;
__ILM_RAM_SIZE = 0x00010000;
/*--------------------- Embedded RAM Configuration ---------------------------
* <h> RAM Configuration
* <o0> RAM Base Address <0x0-0xFFFFFFFF:8>
* <o1> RAM Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__RAM_BASE = 0x20000000;
__RAM_SIZE = 0x00005000;
/********************* Stack / Heap Configuration ****************************
* <h> Stack / Heap Configuration
* <o0> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
* <o1> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
* </h>
*/
__STACK_SIZE = 0x00000800;
__HEAP_SIZE = 0x00000800;
/**************************** end of configuration section ********************/
/* Define base address and length of flash and ram */
MEMORY
{
flash (rxai!w) : ORIGIN = __ROM_BASE, LENGTH = __ROM_SIZE
ram (wxa!ri) : ORIGIN = __RAM_BASE, LENGTH = __RAM_SIZE
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH,ILM and RAM.
* It references following symbols, which must be defined in code:
* _Start : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* _ilm_lma
* _ilm
* __etext
* _etext
* etext
* _eilm
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* _data_lma
* _edata
* edata
* __data_end__
* __bss_start
* __fbss
* _end
* end
* __heap_end
* __StackLimit
* __StackTop
* __STACK_SIZE
*/
/* Define entry label of program */
ENTRY(_start)
SECTIONS
{
__STACK_SIZE = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2K;
.init :
{
/* vector table locate at flash */
*(.vtable)
KEEP (*(SORT_NONE(.init)))
} >flash AT>flash
.ilalign :
{
. = ALIGN(4);
/* Create a section label as _ilm_lma which located at flash */
PROVIDE( _ilm_lma = . );
} >flash AT>flash
.ialign :
{
/* Create a section label as _ilm which located at flash */
PROVIDE( _ilm = . );
} >flash AT>flash
/* Code section located at flash */
.text :
{
*(.text.unlikely .text.unlikely.*)
*(.text.startup .text.startup.*)
*(.text .text.*)
*(.gnu.linkonce.t.*)
} >flash AT>flash
.rodata : ALIGN(4)
{
. = ALIGN(4);
*(.rdata)
*(.rodata .rodata.*)
/* section information for initial. */
. = ALIGN(4);
__rt_init_start = .;
KEEP(*(SORT(.rti_fn*)))
__rt_init_end = .;
/* section information for finsh shell */
. = ALIGN(4);
__fsymtab_start = .;
KEEP(*(FSymTab))
__fsymtab_end = .;
. = ALIGN(4);
__vsymtab_start = .;
KEEP(*(VSymTab))
__vsymtab_end = .;
*(.gnu.linkonce.r.*)
. = ALIGN(8);
*(.srodata.cst16)
*(.srodata.cst8)
*(.srodata.cst4)
*(.srodata.cst2)
*(.srodata .srodata.*)
} >flash AT>flash
.fini :
{
KEEP (*(SORT_NONE(.fini)))
} >flash AT>flash
. = ALIGN(4);
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
PROVIDE( _eilm = . );
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
} >flash AT>flash
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
} >flash AT>flash
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
} >flash AT>flash
.ctors :
{
/* gcc uses crtbegin.o to find the start of
* the constructors, so we make sure it is
* first. Because this is a wildcard, it
* doesn't matter if the user does not
* actually link against crtbegin.o; the
* linker won't look for a file to match a
* wildcard. The wildcard also means that it
* doesn't matter which directory crtbegin.o
* is in.
*/
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
* the crtend.o file until after the sorted ctors.
* The .ctor section from the crtend file contains the
* end of ctors marker and it must be last
*/
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
} >flash AT>flash
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
} >flash AT>flash
.lalign :
{
. = ALIGN(4);
PROVIDE( _data_lma = . );
} >flash AT>flash
.dalign :
{
. = ALIGN(4);
PROVIDE( _data = . );
} >ram AT>flash
/* Define data section virtual address is ram and physical address is flash */
.data :
{
*(.data .data.*)
*(.gnu.linkonce.d.*)
. = ALIGN(8);
PROVIDE( __global_pointer$ = . + 0x800 );
*(.sdata .sdata.* .sdata*)
*(.gnu.linkonce.s.*)
} >ram AT>flash
. = ALIGN(4);
PROVIDE( _edata = . );
PROVIDE( edata = . );
PROVIDE( _fbss = . );
PROVIDE( __bss_start = . );
.bss :
{
*(.sbss*)
*(.gnu.linkonce.sb.*)
*(.bss .bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(4);
} >ram AT>ram
. = ALIGN(8);
PROVIDE( _end = . );
PROVIDE( end = . );
/* Define stack and head location at ram */
.stack ORIGIN(ram) + LENGTH(ram) - __STACK_SIZE :
{
PROVIDE( _heap_end = . );
. = __STACK_SIZE;
PROVIDE( _sp = . );
} >ram AT>ram
}

View File

@@ -0,0 +1,39 @@
/*!
\file gd32vf103v_eval.c
\brief firmware functions to manage leds, keys, COM ports
\version 2019-6-5, V1.0.0, demo for GD32VF103
*/
/*
Copyright (c) 2019, GigaDevice Semiconductor Inc.
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.
*/
#include "nuclei_sdk_hal.h"
#include "gd32vf103_usart.h"
#include "gd32vf103_gpio.h"
#include "gd32vf103_exti.h"

View File

@@ -0,0 +1,47 @@
adapter_khz 1000
reset_config srst_only
adapter_nsrst_assert_width 100
interface cmsis-dap
transport select jtag
autoexit true
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x1e200a6d
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-phys 0x20000000 -work-area-size 20480 -work-area-backup 0
# Work-area is a space in RAM used for flash programming
if { [info exists WORKAREASIZE] } {
set _WORKAREASIZE $WORKAREASIZE
} else {
set _WORKAREASIZE 0x5000
}
# Allow overriding the Flash bank size
if { [info exists FLASH_SIZE] } {
set _FLASH_SIZE $FLASH_SIZE
} else {
# autodetect size
set _FLASH_SIZE 0
}
# flash size will be probed
set _FLASHNAME $_CHIPNAME.flash
flash bank $_FLASHNAME gd32vf103 0x08000000 0 0 0 $_TARGETNAME
# Expose Nuclei self-defined CSRS range 770-800,835-850,1984-2032,2064-2070
# See https://github.com/riscv/riscv-gnu-toolchain/issues/319#issuecomment-358397306
# Then user can view the csr register value in gdb using: info reg csr775 for CSR MTVT(0x307)
riscv expose_csrs 770-800,835-850,1984-2032,2064-2070
riscv set_reset_timeout_sec 1
init
halt

View File

@@ -1,4 +1,4 @@
adapter_khz 1000 adapter_khz 4000
reset_config srst_only reset_config srst_only
adapter_nsrst_assert_width 100 adapter_nsrst_assert_width 100

0
workspace/TS100/Core/Drivers/BMA223.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/BMA223.hpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/BMA223_defines.h Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/Buttons.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/Buttons.hpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/FUSB302/fusb302b.h Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/FUSB302/fusbpd.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/FUSB302/fusbpd.h Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/FUSB302/int_n.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/FUSB302/int_n.h Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/FUSB302/pd.h Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/FUSB302/pdb_conf.h Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/FUSB302/pdb_msg.h Normal file → Executable file
View File

967
workspace/TS100/Core/Drivers/FUSB302/policy_engine.cpp Normal file → Executable file

File diff suppressed because it is too large Load Diff

241
workspace/TS100/Core/Drivers/FUSB302/policy_engine.h Normal file → Executable file
View File

@@ -34,166 +34,165 @@
#define PDB_EVT_PE_MSG_RX_PEND EVENT_MASK(7) /* Never SEND THIS DIRECTLY*/ #define PDB_EVT_PE_MSG_RX_PEND EVENT_MASK(7) /* Never SEND THIS DIRECTLY*/
class PolicyEngine { class PolicyEngine {
public: public:
//Sets up internal state and registers the thread //Sets up internal state and registers the thread
static void init(); static void init();
//Push an incoming message to the Policy Engine //Push an incoming message to the Policy Engine
static void handleMessage(union pd_msg *msg); static void handleMessage(union pd_msg *msg);
//Send a notification //Send a notification
static void notify(uint32_t notification); static void notify(uint32_t notification);
//Returns true if headers indicate PD3.0 compliant //Returns true if headers indicate PD3.0 compliant
static bool isPD3_0(); static bool isPD3_0();
static bool setupCompleteOrTimedOut() { static bool setupCompleteOrTimedOut() {
if (pdNegotiationComplete) if (pdNegotiationComplete)
return true; return true;
if (state == policy_engine_state::PESinkSourceUnresponsive) if (state == policy_engine_state::PESinkSourceUnresponsive)
return true; return true;
if (state == policy_engine_state::PESinkReady) if (state == policy_engine_state::PESinkReady)
return true; return true;
return false; return false;
} }
//Has pd negotiation completed //Has pd negotiation completed
static bool pdHasNegotiated() { static bool pdHasNegotiated() {
return pdNegotiationComplete; return pdNegotiationComplete;
} }
private:
private: static bool pdNegotiationComplete;
static bool pdNegotiationComplete; static int current_voltage_mv; //The current voltage PD is expecting
static int current_voltage_mv; //The current voltage PD is expecting static int _requested_voltage; //The voltage the unit wanted to requests
static int _requested_voltage; //The voltage the unit wanted to requests static bool _unconstrained_power; // If the source is unconstrained
static bool _unconstrained_power; // If the source is unconstrained //Current message being handled
//Current message being handled static union pd_msg currentMessage;
static union pd_msg currentMessage; /* PD message header template */
/* PD message header template */ static uint16_t hdr_template;
static uint16_t hdr_template; /* Whether or not we have an explicit contract */
/* Whether or not we have an explicit contract */ static bool _explicit_contract;
static bool _explicit_contract; /* The number of hard resets we've sent */
/* The number of hard resets we've sent */ static int8_t _hard_reset_counter;
static int8_t _hard_reset_counter; /* The result of the last Type-C Current match comparison */
/* The result of the last Type-C Current match comparison */ static int8_t _old_tcc_match;
static int8_t _old_tcc_match; /* The index of the first PPS APDO */
/* The index of the first PPS APDO */ static uint8_t _pps_index;
static uint8_t _pps_index; /* The index of the just-requested PPS APDO */
/* The index of the just-requested PPS APDO */ static uint8_t _last_pps;
static uint8_t _last_pps; static void pe_task(const void *arg);
static void pe_task(const void *arg); enum policy_engine_state {
enum policy_engine_state { PESinkStartup,
PESinkStartup, PESinkDiscovery,
PESinkDiscovery, PESinkWaitCap,
PESinkWaitCap, PESinkEvalCap,
PESinkEvalCap, PESinkSelectCap,
PESinkSelectCap, PESinkTransitionSink,
PESinkTransitionSink, PESinkReady,
PESinkReady, PESinkGetSourceCap,
PESinkGetSourceCap, PESinkGiveSinkCap,
PESinkGiveSinkCap, PESinkHardReset,
PESinkHardReset, PESinkTransitionDefault,
PESinkTransitionDefault, PESinkSoftReset,
PESinkSoftReset, PESinkSendSoftReset,
PESinkSendSoftReset, PESinkSendNotSupported,
PESinkSendNotSupported, PESinkChunkReceived,
PESinkChunkReceived, PESinkNotSupportedReceived,
PESinkNotSupportedReceived, PESinkSourceUnresponsive
PESinkSourceUnresponsive };
}; static enum policy_engine_state pe_sink_startup();
static enum policy_engine_state pe_sink_startup(); static enum policy_engine_state pe_sink_discovery();
static enum policy_engine_state pe_sink_discovery(); static enum policy_engine_state pe_sink_wait_cap();
static enum policy_engine_state pe_sink_wait_cap(); static enum policy_engine_state pe_sink_eval_cap();
static enum policy_engine_state pe_sink_eval_cap(); static enum policy_engine_state pe_sink_select_cap();
static enum policy_engine_state pe_sink_select_cap(); static enum policy_engine_state pe_sink_transition_sink();
static enum policy_engine_state pe_sink_transition_sink(); static enum policy_engine_state pe_sink_ready();
static enum policy_engine_state pe_sink_ready(); static enum policy_engine_state pe_sink_get_source_cap();
static enum policy_engine_state pe_sink_get_source_cap(); static enum policy_engine_state pe_sink_give_sink_cap();
static enum policy_engine_state pe_sink_give_sink_cap(); static enum policy_engine_state pe_sink_hard_reset();
static enum policy_engine_state pe_sink_hard_reset(); static enum policy_engine_state pe_sink_transition_default();
static enum policy_engine_state pe_sink_transition_default(); static enum policy_engine_state pe_sink_soft_reset();
static enum policy_engine_state pe_sink_soft_reset(); static enum policy_engine_state pe_sink_send_soft_reset();
static enum policy_engine_state pe_sink_send_soft_reset(); static enum policy_engine_state pe_sink_send_not_supported();
static enum policy_engine_state pe_sink_send_not_supported(); static enum policy_engine_state pe_sink_chunk_received();
static enum policy_engine_state pe_sink_chunk_received(); static enum policy_engine_state pe_sink_not_supported_received();
static enum policy_engine_state pe_sink_not_supported_received(); static enum policy_engine_state pe_sink_source_unresponsive();
static enum policy_engine_state pe_sink_source_unresponsive(); static EventGroupHandle_t xEventGroupHandle;
static EventGroupHandle_t xEventGroupHandle; static StaticEventGroup_t xCreatedEventGroup;
static StaticEventGroup_t xCreatedEventGroup; static uint32_t waitForEvent(uint32_t mask, TickType_t ticksToWait =
static uint32_t waitForEvent(uint32_t mask, TickType_t ticksToWait = portMAX_DELAY);
portMAX_DELAY); //Task resources
//Task resources static osThreadId TaskHandle;
static osThreadId TaskHandle; static const size_t TaskStackSize = 2048 / 4;
static const size_t TaskStackSize = 2048 / 4; static uint32_t TaskBuffer[TaskStackSize];
static uint32_t TaskBuffer[TaskStackSize]; static osStaticThreadDef_t TaskControlBlock;
static osStaticThreadDef_t TaskControlBlock; static union pd_msg tempMessage;
static union pd_msg tempMessage; static union pd_msg _last_dpm_request;
static union pd_msg _last_dpm_request; static policy_engine_state state;
static policy_engine_state state; //queue of up to PDB_MSG_POOL_SIZE messages to send
//queue of up to PDB_MSG_POOL_SIZE messages to send static StaticQueue_t xStaticQueue;
static StaticQueue_t xStaticQueue; /* The array to use as the queue's storage area. This must be at least
/* The array to use as the queue's storage area. This must be at least
uxQueueLength * uxItemSize bytes. */ uxQueueLength * uxItemSize bytes. */
static uint8_t ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)]; static uint8_t ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)];
static QueueHandle_t messagesWaiting; static QueueHandle_t messagesWaiting;
static bool messageWaiting(); static bool messageWaiting();
//Read a pending message into the temp message //Read a pending message into the temp message
static bool readMessage(); static bool readMessage();
// These callbacks are called to implement the logic for the iron to select the desired voltage // These callbacks are called to implement the logic for the iron to select the desired voltage
/* /*
* Create a Request message based on the given Source_Capabilities message. If * Create a Request message based on the given Source_Capabilities message. If
* capabilities is NULL, the last non-null Source_Capabilities message passes * capabilities is NULL, the last non-null Source_Capabilities message passes
* is used. If none has been provided, the behavior is undefined. * is used. If none has been provided, the behavior is undefined.
* *
* Returns true if sufficient power is available, false otherwise. * Returns true if sufficient power is available, false otherwise.
*/ */
static bool pdbs_dpm_evaluate_capability(const union pd_msg *capabilities, static bool pdbs_dpm_evaluate_capability(const union pd_msg *capabilities,
union pd_msg *request); union pd_msg *request);
/* /*
* Create a Sink_Capabilities message for our current capabilities. * Create a Sink_Capabilities message for our current capabilities.
*/ */
static void pdbs_dpm_get_sink_capability(union pd_msg *cap); static void pdbs_dpm_get_sink_capability(union pd_msg *cap);
/* /*
* Return whether or not GiveBack support is enabled. * Return whether or not GiveBack support is enabled.
*/ */
static bool pdbs_dpm_giveback_enabled(); static bool pdbs_dpm_giveback_enabled();
/* /*
* Evaluate whether or not the currently offered Type-C Current can fulfill our * Evaluate whether or not the currently offered Type-C Current can fulfill our
* power needs. * power needs.
* *
* Returns true if sufficient power is available, false otherwise. * Returns true if sufficient power is available, false otherwise.
*/ */
static bool pdbs_dpm_evaluate_typec_current(enum fusb_typec_current tcc); static bool pdbs_dpm_evaluate_typec_current(enum fusb_typec_current tcc);
/* /*
* Indicate that power negotiations are starting. * Indicate that power negotiations are starting.
*/ */
static void pdbs_dpm_pd_start(); static void pdbs_dpm_pd_start();
/* /*
* Transition the sink to default power. * Transition the sink to default power.
*/ */
static void pdbs_dpm_transition_default(); static void pdbs_dpm_transition_default();
/* /*
* Transition to the requested minimum current. * Transition to the requested minimum current.
*/ */
static void pdbs_dpm_transition_min(); static void pdbs_dpm_transition_min();
/* /*
* Transition to Sink Standby if necessary. * Transition to Sink Standby if necessary.
*/ */
static void pdbs_dpm_transition_standby(); static void pdbs_dpm_transition_standby();
/* /*
* Transition to the requested power level * Transition to the requested power level
*/ */
static void pdbs_dpm_transition_requested(); static void pdbs_dpm_transition_requested();
/* /*
* Transition to the Type-C Current power level * Transition to the Type-C Current power level
*/ */
static void pdbs_dpm_transition_typec(); static void pdbs_dpm_transition_typec();
}; };
#endif /* PDB_POLICY_ENGINE_H */ #endif /* PDB_POLICY_ENGINE_H */

View File

215
workspace/TS100/Core/Drivers/FUSB302/protocol_rx.cpp Normal file → Executable file
View File

@@ -17,12 +17,12 @@
#include "protocol_rx.h" #include "protocol_rx.h"
#include "fusb302b.h" #include <stdlib.h>
#include "policy_engine.h"
#include "protocol_tx.h"
#include "string.h" #include "string.h"
#include <pd.h> #include <pd.h>
#include <stdlib.h> #include "policy_engine.h"
#include "protocol_tx.h"
#include "fusb302b.h"
osThreadId ProtocolReceive::TaskHandle = NULL; osThreadId ProtocolReceive::TaskHandle = NULL;
EventGroupHandle_t ProtocolReceive::xEventGroupHandle = NULL; EventGroupHandle_t ProtocolReceive::xEventGroupHandle = NULL;
StaticEventGroup_t ProtocolReceive::xCreatedEventGroup; StaticEventGroup_t ProtocolReceive::xCreatedEventGroup;
@@ -35,154 +35,155 @@ uint8_t ProtocolReceive::_tx_messageidcounter;
* PRL_Rx_Wait_for_PHY_Message state * PRL_Rx_Wait_for_PHY_Message state
*/ */
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_wait_phy() { ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_wait_phy() {
/* Wait for an event */ /* Wait for an event */
_rx_messageid = 0; _rx_messageid = 0;
eventmask_t evt = waitForEvent( eventmask_t evt = waitForEvent(
PDB_EVT_PRLRX_RESET | PDB_EVT_PRLRX_I_GCRCSENT | PDB_EVT_PRLRX_I_RXPEND); PDB_EVT_PRLRX_RESET | PDB_EVT_PRLRX_I_GCRCSENT | PDB_EVT_PRLRX_I_RXPEND);
/* If we got a reset event, reset */ /* If we got a reset event, reset */
if (evt & PDB_EVT_PRLRX_RESET) { if (evt & PDB_EVT_PRLRX_RESET) {
waitForEvent(PDB_EVT_PRLRX_RESET, 0); waitForEvent(PDB_EVT_PRLRX_RESET, 0);
return PRLRxWaitPHY; return PRLRxWaitPHY;
} }
/* If we got an I_GCRCSENT event, read the message and decide what to do */ /* If we got an I_GCRCSENT event, read the message and decide what to do */
if (evt & PDB_EVT_PRLRX_I_GCRCSENT) { if (evt & PDB_EVT_PRLRX_I_GCRCSENT) {
/* Get a buffer to read the message into. Guaranteed to not fail /* Get a buffer to read the message into. Guaranteed to not fail
* because we have a big enough pool and are careful. */ * because we have a big enough pool and are careful. */
union pd_msg *_rx_message = &tempMessage; union pd_msg *_rx_message = &tempMessage;
memset(&tempMessage, 0, sizeof(tempMessage)); memset(&tempMessage, 0, sizeof(tempMessage));
/* Read the message */ /* Read the message */
fusb_read_message(_rx_message); fusb_read_message(_rx_message);
/* If it's a Soft_Reset, go to the soft reset state */ /* If it's a Soft_Reset, go to the soft reset state */
if (PD_MSGTYPE_GET(_rx_message) == PD_MSGTYPE_SOFT_RESET && PD_NUMOBJ_GET(_rx_message) == 0) { if (PD_MSGTYPE_GET(_rx_message) == PD_MSGTYPE_SOFT_RESET
return PRLRxReset; && PD_NUMOBJ_GET(_rx_message) == 0) {
} else { return PRLRxReset;
/* Otherwise, check the message ID */ } else {
return PRLRxCheckMessageID; /* Otherwise, check the message ID */
} return PRLRxCheckMessageID;
} else if (evt & PDB_EVT_PRLRX_I_RXPEND) { }
//There is an RX message pending that is not a Good CRC } else if (evt & PDB_EVT_PRLRX_I_RXPEND) {
union pd_msg *_rx_message = &tempMessage; //There is an RX message pending that is not a Good CRC
/* Read the message */ union pd_msg *_rx_message = &tempMessage;
fusb_read_message(_rx_message); /* Read the message */
return PRLRxWaitPHY; fusb_read_message(_rx_message);
} return PRLRxWaitPHY;
}
return PRLRxWaitPHY; return PRLRxWaitPHY;
} }
/* /*
* PRL_Rx_Layer_Reset_for_Receive state * PRL_Rx_Layer_Reset_for_Receive state
*/ */
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_reset() { ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_reset() {
/* Reset MessageIDCounter */ /* Reset MessageIDCounter */
_tx_messageidcounter = 0; _tx_messageidcounter = 0;
/* Clear stored MessageID */ /* Clear stored MessageID */
_rx_messageid = -1; _rx_messageid = -1;
/* TX transitions to its reset state */ /* TX transitions to its reset state */
ProtocolTransmit::notify( ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_RESET); ProtocolTransmit::Notifications::PDB_EVT_PRLTX_RESET);
taskYIELD(); taskYIELD();
/* If we got a RESET signal, reset the machine */ /* If we got a RESET signal, reset the machine */
if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) != 0) { if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) != 0) {
return PRLRxWaitPHY; return PRLRxWaitPHY;
} }
/* Go to the Check_MessageID state */ /* Go to the Check_MessageID state */
return PRLRxCheckMessageID; return PRLRxCheckMessageID;
} }
volatile uint32_t rxCounter = 0; volatile uint32_t rxCounter = 0;
/* /*
* PRL_Rx_Check_MessageID state * PRL_Rx_Check_MessageID state
*/ */
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_check_messageid() { ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_check_messageid() {
/* If we got a RESET signal, reset the machine */ /* If we got a RESET signal, reset the machine */
// if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) == PDB_EVT_PRLRX_RESET) { // if (waitForEvent(PDB_EVT_PRLRX_RESET, 0) == PDB_EVT_PRLRX_RESET) {
// return PRLRxWaitPHY; // return PRLRxWaitPHY;
// } // }
/* If the message has the stored ID, we've seen this message before. Free /* If the message has the stored ID, we've seen this message before. Free
* it and don't pass it to the policy engine. */ * it and don't pass it to the policy engine. */
/* Otherwise, there's either no stored ID or this message has an ID we /* Otherwise, there's either no stored ID or this message has an ID we
* haven't just seen. Transition to the Store_MessageID state. */ * haven't just seen. Transition to the Store_MessageID state. */
// if (PD_MESSAGEID_GET(&tempMessage) == _rx_messageid) { // if (PD_MESSAGEID_GET(&tempMessage) == _rx_messageid) {
// return PRLRxWaitPHY; // return PRLRxWaitPHY;
// } else // } else
{ {
rxCounter++; rxCounter++;
return PRLRxStoreMessageID; return PRLRxStoreMessageID;
} }
} }
/* /*
* PRL_Rx_Store_MessageID state * PRL_Rx_Store_MessageID state
*/ */
ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_store_messageid() { ProtocolReceive::protocol_rx_state ProtocolReceive::protocol_rx_store_messageid() {
/* Tell ProtocolTX to discard the message being transmitted */ /* Tell ProtocolTX to discard the message being transmitted */
ProtocolTransmit::notify( ProtocolTransmit::notify(
ProtocolTransmit::Notifications::PDB_EVT_PRLTX_DISCARD); ProtocolTransmit::Notifications::PDB_EVT_PRLTX_DISCARD);
/* Update the stored MessageID */ /* Update the stored MessageID */
_rx_messageid = PD_MESSAGEID_GET(&tempMessage); _rx_messageid = PD_MESSAGEID_GET(&tempMessage);
/* Pass the message to the policy engine. */ /* Pass the message to the policy engine. */
PolicyEngine::handleMessage(&tempMessage); PolicyEngine::handleMessage(&tempMessage);
PolicyEngine::notify(PDB_EVT_PE_MSG_RX); PolicyEngine::notify(PDB_EVT_PE_MSG_RX);
taskYIELD(); taskYIELD();
/* Don't check if we got a RESET because we'd do nothing different. */ /* Don't check if we got a RESET because we'd do nothing different. */
return PRLRxWaitPHY; return PRLRxWaitPHY;
} }
void ProtocolReceive::init() { void ProtocolReceive::init() {
osThreadStaticDef(protRX, thread, PDB_PRIO_PRL, 0, TaskStackSize, osThreadStaticDef(protRX, thread, PDB_PRIO_PRL, 0, TaskStackSize,
TaskBuffer, &TaskControlBlock); TaskBuffer, &TaskControlBlock);
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup); xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
TaskHandle = osThreadCreate(osThread(protRX), NULL); TaskHandle = osThreadCreate(osThread(protRX), NULL);
} }
void ProtocolReceive::thread(const void *args) { void ProtocolReceive::thread(const void *args) {
(void)args; (void) args;
ProtocolReceive::protocol_rx_state state = PRLRxWaitPHY; ProtocolReceive::protocol_rx_state state = PRLRxWaitPHY;
while (true) { while (true) {
switch (state) { switch (state) {
case PRLRxWaitPHY: case PRLRxWaitPHY:
state = protocol_rx_wait_phy(); state = protocol_rx_wait_phy();
break; break;
case PRLRxReset: case PRLRxReset:
state = protocol_rx_reset(); state = protocol_rx_reset();
break; break;
case PRLRxCheckMessageID: case PRLRxCheckMessageID:
state = protocol_rx_check_messageid(); state = protocol_rx_check_messageid();
break; break;
case PRLRxStoreMessageID: case PRLRxStoreMessageID:
state = protocol_rx_store_messageid(); state = protocol_rx_store_messageid();
break; break;
default: default:
/* This is an error. It really shouldn't happen. We might /* This is an error. It really shouldn't happen. We might
* want to handle it anyway, though. */ * want to handle it anyway, though. */
state = PRLRxWaitPHY; state = PRLRxWaitPHY;
break; break;
} }
} }
} }
void ProtocolReceive::notify(uint32_t notification) { void ProtocolReceive::notify(uint32_t notification) {
if (xEventGroupHandle != NULL) { if (xEventGroupHandle != NULL) {
xEventGroupSetBits(xEventGroupHandle, notification); xEventGroupSetBits(xEventGroupHandle, notification);
} }
} }
uint32_t ProtocolReceive::waitForEvent(uint32_t mask, TickType_t ticksToWait) { uint32_t ProtocolReceive::waitForEvent(uint32_t mask, TickType_t ticksToWait) {
if (xEventGroupHandle != NULL) { if (xEventGroupHandle != NULL) {
return xEventGroupWaitBits(xEventGroupHandle, mask, mask, return xEventGroupWaitBits(xEventGroupHandle, mask, mask,
pdFALSE, ticksToWait); pdFALSE, ticksToWait);
} }
return 0; return 0;
} }

53
workspace/TS100/Core/Drivers/FUSB302/protocol_rx.h Normal file → Executable file
View File

@@ -28,40 +28,37 @@
#define PDB_EVT_PRLRX_I_RXPEND EVENT_MASK(2) #define PDB_EVT_PRLRX_I_RXPEND EVENT_MASK(2)
class ProtocolReceive { class ProtocolReceive {
public: public:
static void init(); static void init();
static void notify(uint32_t notification); static void notify(uint32_t notification);
private:
static void thread(const void *args);
private: static EventGroupHandle_t xEventGroupHandle;
static void thread(const void *args); static StaticEventGroup_t xCreatedEventGroup;
static osThreadId TaskHandle;
static EventGroupHandle_t xEventGroupHandle; static const size_t TaskStackSize = 1024 / 4;
static StaticEventGroup_t xCreatedEventGroup; static uint32_t TaskBuffer[TaskStackSize];
static osThreadId TaskHandle; static osStaticThreadDef_t TaskControlBlock;
static const size_t TaskStackSize = 1024 / 4; /*
static uint32_t TaskBuffer[TaskStackSize];
static osStaticThreadDef_t TaskControlBlock;
/*
* Protocol RX machine states * Protocol RX machine states
* *
* There is no Send_GoodCRC state because the PHY sends the GoodCRC for us. * There is no Send_GoodCRC state because the PHY sends the GoodCRC for us.
* All transitions that would go to that state instead go to Check_MessageID. * All transitions that would go to that state instead go to Check_MessageID.
*/ */
enum protocol_rx_state { enum protocol_rx_state {
PRLRxWaitPHY, PRLRxWaitPHY, PRLRxReset, PRLRxCheckMessageID, PRLRxStoreMessageID
PRLRxReset, };
PRLRxCheckMessageID, static protocol_rx_state protocol_rx_store_messageid();
PRLRxStoreMessageID static protocol_rx_state protocol_rx_check_messageid();
}; static protocol_rx_state protocol_rx_reset();
static protocol_rx_state protocol_rx_store_messageid(); static protocol_rx_state protocol_rx_wait_phy();
static protocol_rx_state protocol_rx_check_messageid(); static union pd_msg tempMessage;
static protocol_rx_state protocol_rx_reset(); static uint8_t _rx_messageid;
static protocol_rx_state protocol_rx_wait_phy(); static uint8_t _tx_messageidcounter;
static union pd_msg tempMessage; static uint32_t waitForEvent(uint32_t mask, TickType_t ticksToWait =
static uint8_t _rx_messageid; portMAX_DELAY);
static uint8_t _tx_messageidcounter;
static uint32_t waitForEvent(uint32_t mask, TickType_t ticksToWait =
portMAX_DELAY);
}; };
#endif /* PDB_PROTOCOL_RX_H */ #endif /* PDB_PROTOCOL_RX_H */

353
workspace/TS100/Core/Drivers/FUSB302/protocol_tx.cpp Normal file → Executable file
View File

@@ -16,18 +16,19 @@
*/ */
#include "protocol_tx.h" #include "protocol_tx.h"
#include "fusb302b.h" #include <pd.h>
#include "fusbpd.h"
#include "policy_engine.h" #include "policy_engine.h"
#include "protocol_rx.h" #include "protocol_rx.h"
#include <pd.h> #include "fusb302b.h"
#include "fusbpd.h"
osThreadId ProtocolTransmit::TaskHandle = NULL; osThreadId ProtocolTransmit::TaskHandle = NULL;
uint32_t ProtocolTransmit::TaskBuffer[ProtocolTransmit::TaskStackSize]; uint32_t ProtocolTransmit::TaskBuffer[ProtocolTransmit::TaskStackSize];
osStaticThreadDef_t ProtocolTransmit::TaskControlBlock; osStaticThreadDef_t ProtocolTransmit::TaskControlBlock;
StaticQueue_t ProtocolTransmit::xStaticQueue; StaticQueue_t ProtocolTransmit::xStaticQueue;
bool ProtocolTransmit::messageSending = false; bool ProtocolTransmit::messageSending = false;
uint8_t ProtocolTransmit::ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)]; uint8_t ProtocolTransmit::ucQueueStorageArea[PDB_MSG_POOL_SIZE
* sizeof(union pd_msg)];
QueueHandle_t ProtocolTransmit::messagesWaiting = NULL; QueueHandle_t ProtocolTransmit::messagesWaiting = NULL;
uint8_t ProtocolTransmit::_tx_messageidcounter; uint8_t ProtocolTransmit::_tx_messageidcounter;
union pd_msg ProtocolTransmit::temp_msg; union pd_msg ProtocolTransmit::temp_msg;
@@ -37,253 +38,261 @@ StaticEventGroup_t ProtocolTransmit::xCreatedEventGroup;
* PRL_Tx_PHY_Layer_Reset state * PRL_Tx_PHY_Layer_Reset state
*/ */
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_phy_reset() { ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_phy_reset() {
/* Reset the PHY */ /* Reset the PHY */
fusb_reset(); fusb_reset();
/* If a message was pending when we got here, tell the policy engine that /* If a message was pending when we got here, tell the policy engine that
* we failed to send it */ * we failed to send it */
if (messagePending()) { if (messagePending()) {
/* Tell the policy engine that we failed */ /* Tell the policy engine that we failed */
PolicyEngine::notify(PDB_EVT_PE_TX_ERR); PolicyEngine::notify( PDB_EVT_PE_TX_ERR);
/* Finish failing to send the message */ /* Finish failing to send the message */
while (messagePending()) { while (messagePending()) {
getMessage(); //Discard getMessage(); //Discard
} }
} }
/* Wait for a message request */ /* Wait for a message request */
return PRLTxWaitMessage; return PRLTxWaitMessage;
} }
/* /*
* PRL_Tx_Wait_for_Message_Request state * PRL_Tx_Wait_for_Message_Request state
*/ */
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_message() { ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_message() {
/* Wait for an event */ /* Wait for an event */
ProtocolTransmit::Notifications evt = waitForEvent( ProtocolTransmit::Notifications evt = waitForEvent(
(uint32_t)Notifications::PDB_EVT_PRLTX_RESET | (uint32_t)Notifications::PDB_EVT_PRLTX_DISCARD | (uint32_t)Notifications::PDB_EVT_PRLTX_MSG_TX); (uint32_t) Notifications::PDB_EVT_PRLTX_RESET
| (uint32_t) Notifications::PDB_EVT_PRLTX_DISCARD
| (uint32_t) Notifications::PDB_EVT_PRLTX_MSG_TX);
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_RESET) { if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_RESET) {
return PRLTxPHYReset; return PRLTxPHYReset;
} }
/* If the policy engine is trying to send a message */ /* If the policy engine is trying to send a message */
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_MSG_TX) { if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_MSG_TX) {
/* Get the message */ /* Get the message */
getMessage(); getMessage();
/* If it's a Soft_Reset, reset the TX layer first */ /* If it's a Soft_Reset, reset the TX layer first */
if (PD_MSGTYPE_GET(&temp_msg) == PD_MSGTYPE_SOFT_RESET && PD_NUMOBJ_GET(&(temp_msg)) == 0) { if (PD_MSGTYPE_GET(&temp_msg) == PD_MSGTYPE_SOFT_RESET
return PRLTxReset; && PD_NUMOBJ_GET(&(temp_msg)) == 0) {
/* Otherwise, just send the message */ return PRLTxReset;
} else { /* Otherwise, just send the message */
return PRLTxConstructMessage; } else {
} return PRLTxConstructMessage;
} }
}
/* Silence the compiler warning */ /* Silence the compiler warning */
return PRLTxWaitMessage; return PRLTxWaitMessage;
} }
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_reset() { ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_reset() {
/* Clear MessageIDCounter */ /* Clear MessageIDCounter */
_tx_messageidcounter = 0; _tx_messageidcounter = 0;
/* Tell the Protocol RX thread to reset */ /* Tell the Protocol RX thread to reset */
ProtocolReceive::notify(PDB_EVT_PRLRX_RESET); ProtocolReceive::notify( PDB_EVT_PRLRX_RESET);
taskYIELD(); taskYIELD();
return PRLTxConstructMessage; return PRLTxConstructMessage;
} }
/* /*
* PRL_Tx_Construct_Message state * PRL_Tx_Construct_Message state
*/ */
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_construct_message() { ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_construct_message() {
/* Set the correct MessageID in the message */ /* Set the correct MessageID in the message */
temp_msg.hdr &= ~PD_HDR_MESSAGEID; temp_msg.hdr &= ~PD_HDR_MESSAGEID;
temp_msg.hdr |= (_tx_messageidcounter % 8) << PD_HDR_MESSAGEID_SHIFT; temp_msg.hdr |= (_tx_messageidcounter % 8) << PD_HDR_MESSAGEID_SHIFT;
/* PD 3.0 collision avoidance */ /* PD 3.0 collision avoidance */
// if (PolicyEngine::isPD3_0()) { // if (PolicyEngine::isPD3_0()) {
// /* If we're starting an AMS, wait for permission to transmit */ // /* If we're starting an AMS, wait for permission to transmit */
// evt = waitForEvent((uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS, // evt = waitForEvent((uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS,
// 0); // 0);
// if ((uint32_t) evt // if ((uint32_t) evt
// & (uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS) { // & (uint32_t) Notifications::PDB_EVT_PRLTX_START_AMS) {
// while (fusb_get_typec_current() != fusb_sink_tx_ok) { // while (fusb_get_typec_current() != fusb_sink_tx_ok) {
// osDelay(1); // osDelay(1);
// } // }
// } // }
// } // }
messageSending = true; messageSending = true;
/* Send the message to the PHY */ /* Send the message to the PHY */
fusb_send_message(&temp_msg); fusb_send_message(&temp_msg);
return PRLTxWaitResponse; return PRLTxWaitResponse;
} }
/* /*
* PRL_Tx_Wait_for_PHY_Response state * PRL_Tx_Wait_for_PHY_Response state
*/ */
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_response() { ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_wait_response() {
/* Wait for an event. There is no need to run CRCReceiveTimer, since the /* Wait for an event. There is no need to run CRCReceiveTimer, since the
* FUSB302B handles that as part of its retry mechanism. */ * FUSB302B handles that as part of its retry mechanism. */
ProtocolTransmit::Notifications evt = waitForEvent( ProtocolTransmit::Notifications evt = waitForEvent(
(uint32_t)Notifications::PDB_EVT_PRLTX_RESET | (uint32_t)Notifications::PDB_EVT_PRLTX_DISCARD | (uint32_t)Notifications::PDB_EVT_PRLTX_I_TXSENT | (uint32_t)Notifications::PDB_EVT_PRLTX_I_RETRYFAIL); (uint32_t) Notifications::PDB_EVT_PRLTX_RESET
| (uint32_t) Notifications::PDB_EVT_PRLTX_DISCARD
| (uint32_t) Notifications::PDB_EVT_PRLTX_I_TXSENT
| (uint32_t) Notifications::PDB_EVT_PRLTX_I_RETRYFAIL);
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_RESET) { if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_RESET) {
return PRLTxPHYReset; return PRLTxPHYReset;
} }
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_DISCARD) { if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_DISCARD) {
return PRLTxDiscardMessage; return PRLTxDiscardMessage;
} }
/* If the message was sent successfully */ /* If the message was sent successfully */
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_I_TXSENT) { if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_I_TXSENT) {
return PRLTxMatchMessageID; return PRLTxMatchMessageID;
} }
/* If the message failed to be sent */ /* If the message failed to be sent */
if ((uint32_t)evt & (uint32_t)Notifications::PDB_EVT_PRLTX_I_RETRYFAIL) { if ((uint32_t) evt & (uint32_t) Notifications::PDB_EVT_PRLTX_I_RETRYFAIL) {
return PRLTxTransmissionError; return PRLTxTransmissionError;
} }
/* Silence the compiler warning */ /* Silence the compiler warning */
return PRLTxDiscardMessage; return PRLTxDiscardMessage;
} }
/* /*
* PRL_Tx_Match_MessageID state * PRL_Tx_Match_MessageID state
*/ */
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_match_messageid() { ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_match_messageid() {
union pd_msg goodcrc; union pd_msg goodcrc;
/* Read the GoodCRC */ /* Read the GoodCRC */
fusb_read_message(&goodcrc); fusb_read_message(&goodcrc);
/* Check that the message is correct */ /* Check that the message is correct */
if (PD_MSGTYPE_GET(&goodcrc) == PD_MSGTYPE_GOODCRC && PD_NUMOBJ_GET(&goodcrc) == 0 && PD_MESSAGEID_GET(&goodcrc) == _tx_messageidcounter) { if (PD_MSGTYPE_GET(&goodcrc) == PD_MSGTYPE_GOODCRC
return PRLTxMessageSent; && PD_NUMOBJ_GET(&goodcrc) == 0
} else { && PD_MESSAGEID_GET(&goodcrc) == _tx_messageidcounter) {
return PRLTxTransmissionError; return PRLTxMessageSent;
} } else {
return PRLTxTransmissionError;
}
} }
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_transmission_error() { ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_transmission_error() {
/* Increment MessageIDCounter */ /* Increment MessageIDCounter */
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8; _tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
/* Tell the policy engine that we failed */ /* Tell the policy engine that we failed */
PolicyEngine::notify(PDB_EVT_PE_TX_ERR); PolicyEngine::notify( PDB_EVT_PE_TX_ERR);
return PRLTxWaitMessage; return PRLTxWaitMessage;
} }
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_message_sent() { ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_message_sent() {
messageSending = false; messageSending = false;
/* Increment MessageIDCounter */ /* Increment MessageIDCounter */
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8; _tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
/* Tell the policy engine that we succeeded */ /* Tell the policy engine that we succeeded */
PolicyEngine::notify(PDB_EVT_PE_TX_DONE); PolicyEngine::notify( PDB_EVT_PE_TX_DONE);
return PRLTxWaitMessage; return PRLTxWaitMessage;
} }
ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_discard_message() { ProtocolTransmit::protocol_tx_state ProtocolTransmit::protocol_tx_discard_message() {
/* If we were working on sending a message, increment MessageIDCounter */ /* If we were working on sending a message, increment MessageIDCounter */
if (messageSending) { if (messageSending) {
_tx_messageidcounter = (_tx_messageidcounter + 1) % 8; _tx_messageidcounter = (_tx_messageidcounter + 1) % 8;
return PRLTxPHYReset; return PRLTxPHYReset;
} else { } else {
return PRLTxWaitMessage; return PRLTxWaitMessage;
} }
} }
void ProtocolTransmit::thread(const void *args) { void ProtocolTransmit::thread(const void *args) {
(void)args; (void) args;
ProtocolTransmit::protocol_tx_state state = PRLTxPHYReset; ProtocolTransmit::protocol_tx_state state = PRLTxPHYReset;
//Init the incoming message queue //Init the incoming message queue
while (true) { while (true) {
switch (state) { switch (state) {
case PRLTxPHYReset: case PRLTxPHYReset:
state = protocol_tx_phy_reset(); state = protocol_tx_phy_reset();
break; break;
case PRLTxWaitMessage: case PRLTxWaitMessage:
state = protocol_tx_wait_message(); state = protocol_tx_wait_message();
break; break;
case PRLTxReset: case PRLTxReset:
state = protocol_tx_reset(); state = protocol_tx_reset();
break; break;
case PRLTxConstructMessage: case PRLTxConstructMessage:
state = protocol_tx_construct_message(); state = protocol_tx_construct_message();
break; break;
case PRLTxWaitResponse: case PRLTxWaitResponse:
state = protocol_tx_wait_response(); state = protocol_tx_wait_response();
break; break;
case PRLTxMatchMessageID: case PRLTxMatchMessageID:
state = protocol_tx_match_messageid(); state = protocol_tx_match_messageid();
break; break;
case PRLTxTransmissionError: case PRLTxTransmissionError:
state = protocol_tx_transmission_error(); state = protocol_tx_transmission_error();
break; break;
case PRLTxMessageSent: case PRLTxMessageSent:
state = protocol_tx_message_sent(); state = protocol_tx_message_sent();
break; break;
case PRLTxDiscardMessage: case PRLTxDiscardMessage:
state = protocol_tx_discard_message(); state = protocol_tx_discard_message();
break; break;
default: default:
state = PRLTxPHYReset; state = PRLTxPHYReset;
break; break;
} }
} }
} }
void ProtocolTransmit::notify(ProtocolTransmit::Notifications notification) { void ProtocolTransmit::notify(ProtocolTransmit::Notifications notification) {
if (xEventGroupHandle != NULL) { if (xEventGroupHandle != NULL) {
xEventGroupSetBits(xEventGroupHandle, (uint32_t)notification); xEventGroupSetBits(xEventGroupHandle, (uint32_t) notification);
} }
} }
void ProtocolTransmit::init() { void ProtocolTransmit::init() {
messagesWaiting = xQueueCreateStatic(PDB_MSG_POOL_SIZE, messagesWaiting = xQueueCreateStatic(PDB_MSG_POOL_SIZE,
sizeof(union pd_msg), ucQueueStorageArea, &xStaticQueue); sizeof(union pd_msg), ucQueueStorageArea, &xStaticQueue);
osThreadStaticDef(pd_txTask, thread, PDB_PRIO_PRL, 0, TaskStackSize, osThreadStaticDef(pd_txTask, thread, PDB_PRIO_PRL, 0, TaskStackSize,
TaskBuffer, &TaskControlBlock); TaskBuffer, &TaskControlBlock);
TaskHandle = osThreadCreate(osThread(pd_txTask), NULL); TaskHandle = osThreadCreate(osThread(pd_txTask), NULL);
xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup); xEventGroupHandle = xEventGroupCreateStatic(&xCreatedEventGroup);
} }
void ProtocolTransmit::pushMessage(union pd_msg *msg) { void ProtocolTransmit::pushMessage(union pd_msg *msg) {
if (messagesWaiting) { if (messagesWaiting) {
xQueueSend(messagesWaiting, msg, 100); xQueueSend(messagesWaiting, msg, 100);
} }
} }
bool ProtocolTransmit::messagePending() { bool ProtocolTransmit::messagePending() {
if (messagesWaiting) { if (messagesWaiting) {
return uxQueueMessagesWaiting(messagesWaiting) > 0; return uxQueueMessagesWaiting(messagesWaiting) > 0;
} }
return false; return false;
} }
void ProtocolTransmit::getMessage() { void ProtocolTransmit::getMessage() {
//Loads the pending message into the buffer //Loads the pending message into the buffer
if (messagesWaiting) { if (messagesWaiting) {
xQueueReceive(messagesWaiting, &temp_msg, 1); xQueueReceive(messagesWaiting, &temp_msg, 1);
} }
} }
ProtocolTransmit::Notifications ProtocolTransmit::waitForEvent(uint32_t mask, ProtocolTransmit::Notifications ProtocolTransmit::waitForEvent(uint32_t mask,
TickType_t ticksToWait) { TickType_t ticksToWait) {
if (xEventGroupHandle) { if (xEventGroupHandle) {
return (Notifications)xEventGroupWaitBits(xEventGroupHandle, mask, return (Notifications) xEventGroupWaitBits(xEventGroupHandle, mask,
mask, mask,
pdFALSE, ticksToWait); pdFALSE, ticksToWait);
} }
return (Notifications)0; return (Notifications)0;
} }

116
workspace/TS100/Core/Drivers/FUSB302/protocol_tx.h Normal file → Executable file
View File

@@ -18,80 +18,80 @@
#ifndef PDB_PROTOCOL_TX_H #ifndef PDB_PROTOCOL_TX_H
#define PDB_PROTOCOL_TX_H #define PDB_PROTOCOL_TX_H
#include <stdint.h>
#include "policy_engine.h" #include "policy_engine.h"
#include "protocol_rx.h" #include "protocol_rx.h"
#include <pd.h> #include <pd.h>
#include <stdint.h>
/* Events for the Protocol TX thread */ /* Events for the Protocol TX thread */
class ProtocolTransmit { class ProtocolTransmit {
public: public:
static void init(); static void init();
//Push a message to the queue to be sent out the pd comms bus //Push a message to the queue to be sent out the pd comms bus
static void pushMessage(union pd_msg *msg); static void pushMessage(union pd_msg *msg);
enum class Notifications { enum class Notifications {
PDB_EVT_PRLTX_RESET = EVENT_MASK(0), // PDB_EVT_PRLTX_RESET = EVENT_MASK(0), //
PDB_EVT_PRLTX_I_TXSENT = EVENT_MASK(1), // PDB_EVT_PRLTX_I_TXSENT = EVENT_MASK(1), //
PDB_EVT_PRLTX_I_RETRYFAIL = EVENT_MASK(2), // PDB_EVT_PRLTX_I_RETRYFAIL = EVENT_MASK(2), //
PDB_EVT_PRLTX_DISCARD = EVENT_MASK(3), // PDB_EVT_PRLTX_DISCARD = EVENT_MASK(3), //
PDB_EVT_PRLTX_MSG_TX = EVENT_MASK(4), // PDB_EVT_PRLTX_MSG_TX = EVENT_MASK(4), //
PDB_EVT_PRLTX_START_AMS = EVENT_MASK(5), // PDB_EVT_PRLTX_START_AMS = EVENT_MASK(5), //
}; };
static void notify(Notifications notification); static void notify(Notifications notification);
private:
private: static void thread(const void *args);
static void thread(const void *args); static EventGroupHandle_t xEventGroupHandle;
static EventGroupHandle_t xEventGroupHandle; static StaticEventGroup_t xCreatedEventGroup;
static StaticEventGroup_t xCreatedEventGroup; static osThreadId TaskHandle;
static osThreadId TaskHandle; static const size_t TaskStackSize = 1024 / 4;
static const size_t TaskStackSize = 1024 / 4; static uint32_t TaskBuffer[TaskStackSize];
static uint32_t TaskBuffer[TaskStackSize]; static osStaticThreadDef_t TaskControlBlock;
static osStaticThreadDef_t TaskControlBlock; static bool messageSending;
static bool messageSending; /*
/*
* Protocol TX machine states * Protocol TX machine states
* *
* Because the PHY can automatically send retries, the Check_RetryCounter state * Because the PHY can automatically send retries, the Check_RetryCounter state
* has been removed, transitions relating to it are modified appropriately, and * has been removed, transitions relating to it are modified appropriately, and
* we don't even keep a RetryCounter. * we don't even keep a RetryCounter.
*/ */
enum protocol_tx_state { enum protocol_tx_state {
PRLTxPHYReset, PRLTxPHYReset,
PRLTxWaitMessage, PRLTxWaitMessage,
PRLTxReset, PRLTxReset,
PRLTxConstructMessage, PRLTxConstructMessage,
PRLTxWaitResponse, PRLTxWaitResponse,
PRLTxMatchMessageID, PRLTxMatchMessageID,
PRLTxTransmissionError, PRLTxTransmissionError,
PRLTxMessageSent, PRLTxMessageSent,
PRLTxDiscardMessage PRLTxDiscardMessage
}; };
//Internal states //Internal states
static protocol_tx_state protocol_tx_discard_message(); static protocol_tx_state protocol_tx_discard_message();
static protocol_tx_state protocol_tx_message_sent(); static protocol_tx_state protocol_tx_message_sent();
static protocol_tx_state protocol_tx_transmission_error(); static protocol_tx_state protocol_tx_transmission_error();
static protocol_tx_state protocol_tx_match_messageid(); static protocol_tx_state protocol_tx_match_messageid();
static protocol_tx_state protocol_tx_wait_response(); static protocol_tx_state protocol_tx_wait_response();
static protocol_tx_state protocol_tx_construct_message(); static protocol_tx_state protocol_tx_construct_message();
static protocol_tx_state protocol_tx_reset(); static protocol_tx_state protocol_tx_reset();
static protocol_tx_state protocol_tx_wait_message(); static protocol_tx_state protocol_tx_wait_message();
static protocol_tx_state protocol_tx_phy_reset(); static protocol_tx_state protocol_tx_phy_reset();
//queue of up to PDB_MSG_POOL_SIZE messages to send //queue of up to PDB_MSG_POOL_SIZE messages to send
static StaticQueue_t xStaticQueue; static StaticQueue_t xStaticQueue;
/* The array to use as the queue's storage area. This must be at least /* The array to use as the queue's storage area. This must be at least
uxQueueLength * uxItemSize bytes. */ uxQueueLength * uxItemSize bytes. */
static uint8_t ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)]; static uint8_t ucQueueStorageArea[PDB_MSG_POOL_SIZE * sizeof(union pd_msg)];
static QueueHandle_t messagesWaiting; static QueueHandle_t messagesWaiting;
static uint8_t _tx_messageidcounter; static uint8_t _tx_messageidcounter;
static bool messagePending(); static bool messagePending();
//Reads a message off the queue into the temp message //Reads a message off the queue into the temp message
static void getMessage(); static void getMessage();
static union pd_msg temp_msg; static union pd_msg temp_msg;
static Notifications waitForEvent(uint32_t mask, TickType_t ticksToWait = static Notifications waitForEvent(uint32_t mask, TickType_t ticksToWait =
portMAX_DELAY); portMAX_DELAY);
}; };
#endif /* PDB_PROTOCOL_TX_H */ #endif /* PDB_PROTOCOL_TX_H */

0
workspace/TS100/Core/Drivers/Font.h Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/I2CBB.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/I2CBB.hpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/I2C_Wrapper.hpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/LIS2DH12.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/LIS2DH12.hpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/LIS2DH12_defines.hpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/MMA8652FC.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/MMA8652FC.hpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/MMA8652FC_defines.h Normal file → Executable file
View File

42
workspace/TS100/Core/Drivers/OLED.cpp Normal file → Executable file
View File

@@ -97,10 +97,12 @@ void OLED::initialize() {
// initialisation data to the OLED. // initialisation data to the OLED.
setDisplayState(DisplayState::ON); setDisplayState(DisplayState::ON);
FRToSI2C::writeRegistersBulk(DEVICEADDR_OLED, OLED_Setup_Array, sizeof(OLED_Setup_Array) / sizeof(OLED_Setup_Array[0])); for (int tries = 0; tries < 10; tries++) {
if (FRToSI2C::writeRegistersBulk(DEVICEADDR_OLED, OLED_Setup_Array, sizeof(OLED_Setup_Array) / sizeof(OLED_Setup_Array[0]))) {
return;
}
}
} }
void OLED::setFramebuffer(uint8_t *buffer) { void OLED::setFramebuffer(uint8_t *buffer) {
if (buffer == NULL) { if (buffer == NULL) {
firstStripPtr = &screenBuffer[FRAMEBUFFER_START]; firstStripPtr = &screenBuffer[FRAMEBUFFER_START];
@@ -176,13 +178,13 @@ void OLED::transitionSecondaryFramebuffer(bool forwardNavigation) {
progress = OLED_WIDTH; progress = OLED_WIDTH;
} }
// When forward, current contents move to the left out. // When forward, current contents move to the left out.
// Otherwise the contents move to the right out. // Otherwise the contents move to the right out.
uint8_t oldStart = forwardNavigation ? 0 : progress; uint8_t oldStart = forwardNavigation ? 0 : progress;
uint8_t oldPrevious = forwardNavigation ? progress - offset : offset; uint8_t oldPrevious = forwardNavigation ? progress - offset : offset;
// Content from the second framebuffer moves in from the right (forward) // Content from the second framebuffer moves in from the right (forward)
// or from the left (not forward). // or from the left (not forward).
uint8_t newStart = forwardNavigation ? OLED_WIDTH - progress : 0; uint8_t newStart = forwardNavigation ? OLED_WIDTH - progress : 0;
uint8_t newEnd = forwardNavigation ? 0 : OLED_WIDTH - progress; uint8_t newEnd = forwardNavigation ? 0 : OLED_WIDTH - progress;
@@ -231,7 +233,7 @@ void OLED::setRotation(bool leftHanded) {
screenBuffer[5] = inLeftHandedMode ? 0 : 32; // display is shifted by 32 in left handed screenBuffer[5] = inLeftHandedMode ? 0 : 32; // display is shifted by 32 in left handed
// mode as driver ram is 128 wide // mode as driver ram is 128 wide
screenBuffer[7] = inLeftHandedMode ? 95 : 0x7F; // End address of the ram segment we are writing to (96 wide) screenBuffer[7] = inLeftHandedMode ? 95 : 0x7F; // End address of the ram segment we are writing to (96 wide)
screenBuffer[9] = inLeftHandedMode ? 0xC8 : 0xC0; screenBuffer[9] = inLeftHandedMode ? 0xC8 : 0xC0;
} }
@@ -245,7 +247,7 @@ void OLED::print(const char *str) {
void OLED::setFont(uint8_t fontNumber) { void OLED::setFont(uint8_t fontNumber) {
if (fontNumber == 1) { if (fontNumber == 1) {
// small font // small font
currentFont = USER_FONT_6x8; currentFont = USER_FONT_6x8;
fontHeight = 8; fontHeight = 8;
fontWidth = 6; fontWidth = 6;
@@ -337,9 +339,9 @@ void OLED::drawSymbol(uint8_t symbolID) {
void OLED::drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t *ptr) { void OLED::drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t *ptr) {
// Splat this from x->x+wide in two strides // Splat this from x->x+wide in two strides
if (x <= -wide) if (x <= -wide)
return; // cutoffleft return; // cutoffleft
if (x > 96) if (x > 96)
return; // cutoff right return; // cutoff right
uint8_t visibleStart = 0; uint8_t visibleStart = 0;
uint8_t visibleEnd = wide; uint8_t visibleEnd = wide;
@@ -353,13 +355,13 @@ void OLED::drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uin
} }
if (y == 0) { if (y == 0) {
// Splat first line of data // Splat first line of data
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) { for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
firstStripPtr[xx + x] = ptr[xx]; firstStripPtr[xx + x] = ptr[xx];
} }
} }
if (y == 8 || height == 16) { if (y == 8 || height == 16) {
// Splat the second line // Splat the second line
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) { for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
secondStripPtr[x + xx] = ptr[xx + (height == 16 ? wide : 0)]; secondStripPtr[x + xx] = ptr[xx + (height == 16 ? wide : 0)];
} }
@@ -373,7 +375,7 @@ void OLED::drawAreaSwapped(int16_t x, int8_t y, uint8_t wide, uint8_t height, co
if (x <= -wide) if (x <= -wide)
return; // cutoffleft return; // cutoffleft
if (x > 96) if (x > 96)
return; // cutoff right return; // cutoff right
uint8_t visibleStart = 0; uint8_t visibleStart = 0;
uint8_t visibleEnd = wide; uint8_t visibleEnd = wide;
@@ -387,14 +389,14 @@ void OLED::drawAreaSwapped(int16_t x, int8_t y, uint8_t wide, uint8_t height, co
} }
if (y == 0) { if (y == 0) {
// Splat first line of data // Splat first line of data
for (uint8_t xx = visibleStart; xx < visibleEnd; xx += 2) { for (uint8_t xx = visibleStart; xx < visibleEnd; xx += 2) {
firstStripPtr[xx + x] = ptr[xx + 1]; firstStripPtr[xx + x] = ptr[xx + 1];
firstStripPtr[xx + x + 1] = ptr[xx]; firstStripPtr[xx + x + 1] = ptr[xx];
} }
} }
if (y == 8 || height == 16) { if (y == 8 || height == 16) {
// Splat the second line // Splat the second line
for (uint8_t xx = visibleStart; xx < visibleEnd; xx += 2) { for (uint8_t xx = visibleStart; xx < visibleEnd; xx += 2) {
secondStripPtr[x + xx] = ptr[xx + 1 + (height == 16 ? wide : 0)]; secondStripPtr[x + xx] = ptr[xx + 1 + (height == 16 ? wide : 0)];
secondStripPtr[x + xx + 1] = ptr[xx + (height == 16 ? wide : 0)]; secondStripPtr[x + xx + 1] = ptr[xx + (height == 16 ? wide : 0)];
@@ -407,7 +409,7 @@ void OLED::fillArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uin
if (x <= -wide) if (x <= -wide)
return; // cutoffleft return; // cutoffleft
if (x > 96) if (x > 96)
return; // cutoff right return; // cutoff right
uint8_t visibleStart = 0; uint8_t visibleStart = 0;
uint8_t visibleEnd = wide; uint8_t visibleEnd = wide;
@@ -421,13 +423,13 @@ void OLED::fillArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uin
} }
if (y == 0) { if (y == 0) {
// Splat first line of data // Splat first line of data
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) { for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
firstStripPtr[xx + x] = value; firstStripPtr[xx + x] = value;
} }
} }
if (y == 8 || height == 16) { if (y == 8 || height == 16) {
// Splat the second line // Splat the second line
for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) { for (uint8_t xx = visibleStart; xx < visibleEnd; xx++) {
secondStripPtr[x + xx] = value; secondStripPtr[x + xx] = value;
} }
@@ -473,7 +475,7 @@ void OLED::drawHeatSymbol(uint8_t state) {
// Draw symbol 14 // Draw symbol 14
// Then draw over it, the bottom 5 pixels always stay. 8 pixels above that are // Then draw over it, the bottom 5 pixels always stay. 8 pixels above that are
// the levels masks the symbol nicely // the levels masks the symbol nicely
state /= 31; // 0-> 8 range state /= 31; // 0-> 8 range
// Then we want to draw down (16-(5+state) // Then we want to draw down (16-(5+state)
uint8_t cursor_x_temp = cursor_x; uint8_t cursor_x_temp = cursor_x;
drawSymbol(14); drawSymbol(14);

0
workspace/TS100/Core/Drivers/OLED.hpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/README.md Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/Si7210.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/Si7210.h Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/Si7210_defines.h Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/TipThermoModel.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Drivers/TipThermoModel.h Normal file → Executable file
View File

0
workspace/TS100/Core/Inc/FreeRTOSHooks.h Normal file → Executable file
View File

0
workspace/TS100/Core/Inc/QC3.h Normal file → Executable file
View File

0
workspace/TS100/Core/Inc/Settings.h Normal file → Executable file
View File

0
workspace/TS100/Core/Inc/Translation.h Normal file → Executable file
View File

0
workspace/TS100/Core/Inc/configuration.h Normal file → Executable file
View File

0
workspace/TS100/Core/Inc/expMovingAverage.h Normal file → Executable file
View File

0
workspace/TS100/Core/Inc/gui.hpp Normal file → Executable file
View File

0
workspace/TS100/Core/Inc/history.hpp Normal file → Executable file
View File

2
workspace/TS100/Core/Inc/main.hpp Normal file → Executable file
View File

@@ -12,7 +12,7 @@ extern "C" {
#endif #endif
void vApplicationStackOverflowHook(TaskHandle_t *pxTask, void vApplicationStackOverflowHook(TaskHandle_t *pxTask,
signed portCHAR *pcTaskName); signed portCHAR *pcTaskName);
//Threads //Threads
void startGUITask(void const *argument); void startGUITask(void const *argument);

0
workspace/TS100/Core/Inc/power.hpp Normal file → Executable file
View File

0
workspace/TS100/Core/Inc/stm32f1xx_hal_conf.h Normal file → Executable file
View File

0
workspace/TS100/Core/Inc/stm32f1xx_it.h Normal file → Executable file
View File

0
workspace/TS100/Core/Src/FreeRTOSHooks.c Normal file → Executable file
View File

0
workspace/TS100/Core/Src/QC3.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Src/Settings.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Src/freertos.c Normal file → Executable file
View File

0
workspace/TS100/Core/Src/gui.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Src/main.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Src/power.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Src/syscalls.c Normal file → Executable file
View File

0
workspace/TS100/Core/Threads/GUIThread.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Threads/MOVThread.cpp Normal file → Executable file
View File

0
workspace/TS100/Core/Threads/PIDThread.cpp Normal file → Executable file
View File