Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
59cb689a45
54 changed files with 968 additions and 233 deletions
|
@ -826,6 +826,13 @@ extern "C" {
|
||||||
#define configSTACK_DEPTH_TYPE uint16_t
|
#define configSTACK_DEPTH_TYPE uint16_t
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef configMESSAGE_BUFFER_LENGTH_TYPE
|
||||||
|
/* Defaults to size_t for backward compatibility, but can be overridden
|
||||||
|
in FreeRTOSConfig.h if lengths will always be less than the number of bytes
|
||||||
|
in a size_t. */
|
||||||
|
#define configMESSAGE_BUFFER_LENGTH_TYPE size_t
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Sanity check the configuration. */
|
/* Sanity check the configuration. */
|
||||||
#if( configUSE_TICKLESS_IDLE != 0 )
|
#if( configUSE_TICKLESS_IDLE != 0 )
|
||||||
#if( INCLUDE_vTaskSuspend != 1 )
|
#if( INCLUDE_vTaskSuspend != 1 )
|
||||||
|
@ -1019,7 +1026,7 @@ typedef struct xSTATIC_TCB
|
||||||
uint32_t ulDummy18;
|
uint32_t ulDummy18;
|
||||||
uint8_t ucDummy19;
|
uint8_t ucDummy19;
|
||||||
#endif
|
#endif
|
||||||
#if( ( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) ) || ( portUSING_MPU_WRAPPERS == 1 ) )
|
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||||
uint8_t uxDummy20;
|
uint8_t uxDummy20;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1122,13 +1129,14 @@ typedef struct xSTATIC_TIMER
|
||||||
StaticListItem_t xDummy2;
|
StaticListItem_t xDummy2;
|
||||||
TickType_t xDummy3;
|
TickType_t xDummy3;
|
||||||
UBaseType_t uxDummy4;
|
UBaseType_t uxDummy4;
|
||||||
void *pvDummy5[ 2 ];
|
void *pvDummy5;
|
||||||
|
TaskFunction_t pvDummy6;
|
||||||
#if( configUSE_TRACE_FACILITY == 1 )
|
#if( configUSE_TRACE_FACILITY == 1 )
|
||||||
UBaseType_t uxDummy6;
|
UBaseType_t uxDummy7;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||||
uint8_t ucDummy7;
|
uint8_t ucDummy8;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} StaticTimer_t;
|
} StaticTimer_t;
|
||||||
|
|
|
@ -693,6 +693,25 @@ size_t xMessageBufferSpaceAvailable( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
*/
|
*/
|
||||||
#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer )
|
#define xMessageBufferSpaceAvailable( xMessageBuffer ) xStreamBufferSpacesAvailable( ( StreamBufferHandle_t ) xMessageBuffer )
|
||||||
|
|
||||||
|
/**
|
||||||
|
* message_buffer.h
|
||||||
|
<pre>
|
||||||
|
size_t xMessageBufferNextLengthBytes( MessageBufferHandle_t xMessageBuffer ) );
|
||||||
|
</pre>
|
||||||
|
* Returns the length (in bytes) of the next message in a message buffer.
|
||||||
|
* Useful if xMessageBufferReceive() returned 0 because the size of the buffer
|
||||||
|
* passed into xMessageBufferReceive() was too small to hold the next message.
|
||||||
|
*
|
||||||
|
* @param xMessageBuffer The handle of the message buffer being queried.
|
||||||
|
*
|
||||||
|
* @return The length (in bytes) of the next message in the message buffer, or 0
|
||||||
|
* if the message buffer is empty.
|
||||||
|
*
|
||||||
|
* \defgroup xMessageBufferNextLengthBytes xMessageBufferNextLengthBytes
|
||||||
|
* \ingroup MessageBufferManagement
|
||||||
|
*/
|
||||||
|
#define xMessageBufferNextLengthBytes( xMessageBuffer ) xStreamBufferNextMessageLengthBytes( ( StreamBufferHandle_t ) xMessageBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* message_buffer.h
|
* message_buffer.h
|
||||||
*
|
*
|
||||||
|
|
|
@ -138,6 +138,7 @@ UBaseType_t MPU_uxEventGroupGetNumber( void* xEventGroup );
|
||||||
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait );
|
size_t MPU_xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, TickType_t xTicksToWait );
|
||||||
size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken );
|
size_t MPU_xStreamBufferSendFromISR( StreamBufferHandle_t xStreamBuffer, const void *pvTxData, size_t xDataLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken );
|
||||||
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait );
|
size_t MPU_xStreamBufferReceive( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, TickType_t xTicksToWait );
|
||||||
|
size_t MPU_xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer );
|
||||||
size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken );
|
size_t MPU_xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer, void *pvRxData, size_t xBufferLengthBytes, BaseType_t * const pxHigherPriorityTaskWoken );
|
||||||
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
|
void MPU_vStreamBufferDelete( StreamBufferHandle_t xStreamBuffer );
|
||||||
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
|
BaseType_t MPU_xStreamBufferIsFull( StreamBufferHandle_t xStreamBuffer );
|
||||||
|
|
|
@ -142,6 +142,7 @@ only for ports that are using the MPU. */
|
||||||
#define xStreamBufferSend MPU_xStreamBufferSend
|
#define xStreamBufferSend MPU_xStreamBufferSend
|
||||||
#define xStreamBufferSendFromISR MPU_xStreamBufferSendFromISR
|
#define xStreamBufferSendFromISR MPU_xStreamBufferSendFromISR
|
||||||
#define xStreamBufferReceive MPU_xStreamBufferReceive
|
#define xStreamBufferReceive MPU_xStreamBufferReceive
|
||||||
|
#define xStreamBufferNextMessageLengthBytes MPU_xStreamBufferNextMessageLengthBytes
|
||||||
#define xStreamBufferReceiveFromISR MPU_xStreamBufferReceiveFromISR
|
#define xStreamBufferReceiveFromISR MPU_xStreamBufferReceiveFromISR
|
||||||
#define vStreamBufferDelete MPU_vStreamBufferDelete
|
#define vStreamBufferDelete MPU_vStreamBufferDelete
|
||||||
#define xStreamBufferIsFull MPU_xStreamBufferIsFull
|
#define xStreamBufferIsFull MPU_xStreamBufferIsFull
|
||||||
|
|
|
@ -233,7 +233,7 @@ typedef void * QueueSetMemberHandle_t;
|
||||||
/**
|
/**
|
||||||
* queue. h
|
* queue. h
|
||||||
* <pre>
|
* <pre>
|
||||||
BaseType_t xQueueSendToToFront(
|
BaseType_t xQueueSendToFront(
|
||||||
QueueHandle_t xQueue,
|
QueueHandle_t xQueue,
|
||||||
const void *pvItemToQueue,
|
const void *pvItemToQueue,
|
||||||
TickType_t xTicksToWait
|
TickType_t xTicksToWait
|
||||||
|
|
|
@ -839,6 +839,8 @@ StreamBufferHandle_t xStreamBufferGenericCreateStatic( size_t xBufferSizeBytes,
|
||||||
uint8_t * const pucStreamBufferStorageArea,
|
uint8_t * const pucStreamBufferStorageArea,
|
||||||
StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
|
StaticStreamBuffer_t * const pxStaticStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
|
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#if( configUSE_TRACE_FACILITY == 1 )
|
#if( configUSE_TRACE_FACILITY == 1 )
|
||||||
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
|
void vStreamBufferSetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer, UBaseType_t uxStreamBufferNumber ) PRIVILEGED_FUNCTION;
|
||||||
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
UBaseType_t uxStreamBufferGetStreamBufferNumber( StreamBufferHandle_t xStreamBuffer ) PRIVILEGED_FUNCTION;
|
||||||
|
|
|
@ -135,7 +135,7 @@ typedef struct xTASK_STATUS
|
||||||
UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */
|
UBaseType_t uxBasePriority; /* The priority to which the task will return if the task's current priority has been inherited to avoid unbounded priority inversion when obtaining a mutex. Only valid if configUSE_MUTEXES is defined as 1 in FreeRTOSConfig.h. */
|
||||||
uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */
|
uint32_t ulRunTimeCounter; /* The total run time allocated to the task so far, as defined by the run time stats clock. See http://www.freertos.org/rtos-run-time-stats.html. Only valid when configGENERATE_RUN_TIME_STATS is defined as 1 in FreeRTOSConfig.h. */
|
||||||
StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */
|
StackType_t *pxStackBase; /* Points to the lowest address of the task's stack area. */
|
||||||
uint16_t usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */
|
configSTACK_DEPTH_TYPE usStackHighWaterMark; /* The minimum amount of stack space that has remained for the task since the task was created. The closer this value is to zero the closer the task has come to overflowing its stack. */
|
||||||
} TaskStatus_t;
|
} TaskStatus_t;
|
||||||
|
|
||||||
/* Possible return values for eTaskConfirmSleepModeStatus(). */
|
/* Possible return values for eTaskConfirmSleepModeStatus(). */
|
||||||
|
|
|
@ -114,7 +114,7 @@ const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
|
||||||
/* Insert the new list item into the list, sorted in xItemValue order.
|
/* Insert the new list item into the list, sorted in xItemValue order.
|
||||||
|
|
||||||
If the list already contains a list item with the same item value then the
|
If the list already contains a list item with the same item value then the
|
||||||
new list item should be placed after it. This ensures that TCB's which are
|
new list item should be placed after it. This ensures that TCBs which are
|
||||||
stored in ready lists (all of which have the same xItemValue value) get a
|
stored in ready lists (all of which have the same xItemValue value) get a
|
||||||
share of the CPU. However, if the xItemValue is the same as the back marker
|
share of the CPU. However, if the xItemValue is the same as the back marker
|
||||||
the iteration loop below will not end. Therefore the value is checked
|
the iteration loop below will not end. Therefore the value is checked
|
||||||
|
|
|
@ -301,7 +301,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
|
|
||||||
QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType )
|
QueueHandle_t xQueueGenericCreateStatic( const UBaseType_t uxQueueLength, const UBaseType_t uxItemSize, uint8_t *pucQueueStorage, StaticQueue_t *pxStaticQueue, const uint8_t ucQueueType )
|
||||||
{
|
{
|
||||||
Queue_t *pxNewQueue;
|
Queue_t *pxNewQueue = NULL;
|
||||||
|
|
||||||
configASSERT( uxQueueLength > ( UBaseType_t ) 0 );
|
configASSERT( uxQueueLength > ( UBaseType_t ) 0 );
|
||||||
|
|
||||||
|
@ -345,6 +345,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
traceQUEUE_CREATE_FAILED( ucQueueType );
|
traceQUEUE_CREATE_FAILED( ucQueueType );
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
return pxNewQueue;
|
return pxNewQueue;
|
||||||
|
@ -397,6 +398,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
traceQUEUE_CREATE_FAILED( ucQueueType );
|
traceQUEUE_CREATE_FAILED( ucQueueType );
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
return pxNewQueue;
|
return pxNewQueue;
|
||||||
|
@ -752,13 +754,23 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )
|
if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )
|
||||||
{
|
{
|
||||||
traceQUEUE_SEND( pxQueue );
|
traceQUEUE_SEND( pxQueue );
|
||||||
xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
|
||||||
|
|
||||||
#if ( configUSE_QUEUE_SETS == 1 )
|
#if ( configUSE_QUEUE_SETS == 1 )
|
||||||
{
|
{
|
||||||
|
UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting;
|
||||||
|
|
||||||
|
xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||||
|
|
||||||
if( pxQueue->pxQueueSetContainer != NULL )
|
if( pxQueue->pxQueueSetContainer != NULL )
|
||||||
{
|
{
|
||||||
if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE )
|
if( ( xCopyPosition == queueOVERWRITE ) && ( uxPreviousMessagesWaiting != ( UBaseType_t ) 0 ) )
|
||||||
|
{
|
||||||
|
/* Do not notify the queue set as an existing item
|
||||||
|
was overwritten in the queue so the number of items
|
||||||
|
in the queue has not changed. */
|
||||||
|
mtCOVERAGE_TEST_MARKER();
|
||||||
|
}
|
||||||
|
else if( prvNotifyQueueSetContainer( pxQueue, xCopyPosition ) != pdFALSE )
|
||||||
{
|
{
|
||||||
/* The queue is a member of a queue set, and posting
|
/* The queue is a member of a queue set, and posting
|
||||||
to the queue set caused a higher priority task to
|
to the queue set caused a higher priority task to
|
||||||
|
@ -805,6 +817,8 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||||
}
|
}
|
||||||
#else /* configUSE_QUEUE_SETS */
|
#else /* configUSE_QUEUE_SETS */
|
||||||
{
|
{
|
||||||
|
xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||||
|
|
||||||
/* If there was a task waiting for data to arrive on the
|
/* If there was a task waiting for data to arrive on the
|
||||||
queue then unblock it now. */
|
queue then unblock it now. */
|
||||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||||
|
|
|
@ -129,7 +129,7 @@ that uses task notifications. */
|
||||||
/*lint -restore (9026) */
|
/*lint -restore (9026) */
|
||||||
|
|
||||||
/* The number of bytes used to hold the length of a message in the buffer. */
|
/* The number of bytes used to hold the length of a message in the buffer. */
|
||||||
#define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( size_t ) )
|
#define sbBYTES_TO_STORE_MESSAGE_LENGTH ( sizeof( configMESSAGE_BUFFER_LENGTH_TYPE ) )
|
||||||
|
|
||||||
/* Bits stored in the ucFlags field of the stream buffer. */
|
/* Bits stored in the ucFlags field of the stream buffer. */
|
||||||
#define sbFLAGS_IS_MESSAGE_BUFFER ( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */
|
#define sbFLAGS_IS_MESSAGE_BUFFER ( ( uint8_t ) 1 ) /* Set if the stream buffer was created as a message buffer, in which case it holds discrete messages rather than a stream. */
|
||||||
|
@ -200,7 +200,7 @@ static size_t prvWriteMessageToBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||||
static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer,
|
static size_t prvReadBytesFromBuffer( StreamBuffer_t *pxStreamBuffer,
|
||||||
uint8_t *pucData,
|
uint8_t *pucData,
|
||||||
size_t xMaxCount,
|
size_t xMaxCount,
|
||||||
size_t xBytesAvailable ); PRIVILEGED_FUNCTION
|
size_t xBytesAvailable ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to
|
* Called by both pxStreamBufferCreate() and pxStreamBufferCreateStatic() to
|
||||||
|
@ -504,6 +504,9 @@ TimeOut_t xTimeOut;
|
||||||
if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
|
if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
|
||||||
{
|
{
|
||||||
xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
|
xRequiredSpace += sbBYTES_TO_STORE_MESSAGE_LENGTH;
|
||||||
|
|
||||||
|
/* Overflow? */
|
||||||
|
configASSERT( xRequiredSpace > xDataLengthBytes );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -540,7 +543,7 @@ TimeOut_t xTimeOut;
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer );
|
traceBLOCKING_ON_STREAM_BUFFER_SEND( xStreamBuffer );
|
||||||
( void ) xTaskNotifyWait( ( uint32_t ) 0, UINT32_MAX, NULL, xTicksToWait );
|
( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
|
||||||
pxStreamBuffer->xTaskWaitingToSend = NULL;
|
pxStreamBuffer->xTaskWaitingToSend = NULL;
|
||||||
|
|
||||||
} while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE );
|
} while( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE );
|
||||||
|
@ -746,7 +749,7 @@ size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
|
||||||
{
|
{
|
||||||
/* Wait for data to be available. */
|
/* Wait for data to be available. */
|
||||||
traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer );
|
traceBLOCKING_ON_STREAM_BUFFER_RECEIVE( xStreamBuffer );
|
||||||
( void ) xTaskNotifyWait( ( uint32_t ) 0, UINT32_MAX, NULL, xTicksToWait );
|
( void ) xTaskNotifyWait( ( uint32_t ) 0, ( uint32_t ) 0, NULL, xTicksToWait );
|
||||||
pxStreamBuffer->xTaskWaitingToReceive = NULL;
|
pxStreamBuffer->xTaskWaitingToReceive = NULL;
|
||||||
|
|
||||||
/* Recheck the data available after blocking. */
|
/* Recheck the data available after blocking. */
|
||||||
|
@ -792,6 +795,50 @@ size_t xReceivedLength = 0, xBytesAvailable, xBytesToStoreMessageLength;
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------*/
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
size_t xStreamBufferNextMessageLengthBytes( StreamBufferHandle_t xStreamBuffer )
|
||||||
|
{
|
||||||
|
StreamBuffer_t * const pxStreamBuffer = ( StreamBuffer_t * ) xStreamBuffer; /*lint !e9087 !e9079 Safe cast as StreamBufferHandle_t is opaque Streambuffer_t. */
|
||||||
|
size_t xReturn, xBytesAvailable, xOriginalTail;
|
||||||
|
configMESSAGE_BUFFER_LENGTH_TYPE xTempReturn;
|
||||||
|
|
||||||
|
configASSERT( pxStreamBuffer );
|
||||||
|
|
||||||
|
/* Ensure the stream buffer is being used as a message buffer. */
|
||||||
|
if( ( pxStreamBuffer->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER ) != ( uint8_t ) 0 )
|
||||||
|
{
|
||||||
|
xBytesAvailable = prvBytesInBuffer( pxStreamBuffer );
|
||||||
|
if( xBytesAvailable > sbBYTES_TO_STORE_MESSAGE_LENGTH )
|
||||||
|
{
|
||||||
|
/* The number of bytes available is greater than the number of bytes
|
||||||
|
required to hold the length of the next message, so another message
|
||||||
|
is available. Return its length without removing the length bytes
|
||||||
|
from the buffer. A copy of the tail is stored so the buffer can be
|
||||||
|
returned to its prior state as the message is not actually being
|
||||||
|
removed from the buffer. */
|
||||||
|
xOriginalTail = pxStreamBuffer->xTail;
|
||||||
|
( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempReturn, sbBYTES_TO_STORE_MESSAGE_LENGTH, xBytesAvailable );
|
||||||
|
xReturn = ( size_t ) xTempReturn;
|
||||||
|
pxStreamBuffer->xTail = xOriginalTail;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* The minimum amount of bytes in a message buffer is
|
||||||
|
( sbBYTES_TO_STORE_MESSAGE_LENGTH + 1 ), so if xBytesAvailable is
|
||||||
|
less than sbBYTES_TO_STORE_MESSAGE_LENGTH the only other valid
|
||||||
|
value is 0. */
|
||||||
|
configASSERT( xBytesAvailable == 0 );
|
||||||
|
xReturn = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xReturn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xReturn;
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
size_t xStreamBufferReceiveFromISR( StreamBufferHandle_t xStreamBuffer,
|
||||||
void *pvRxData,
|
void *pvRxData,
|
||||||
size_t xBufferLengthBytes,
|
size_t xBufferLengthBytes,
|
||||||
|
@ -856,6 +903,7 @@ static size_t prvReadMessageFromBuffer( StreamBuffer_t *pxStreamBuffer,
|
||||||
size_t xBytesToStoreMessageLength )
|
size_t xBytesToStoreMessageLength )
|
||||||
{
|
{
|
||||||
size_t xOriginalTail, xReceivedLength, xNextMessageLength;
|
size_t xOriginalTail, xReceivedLength, xNextMessageLength;
|
||||||
|
configMESSAGE_BUFFER_LENGTH_TYPE xTempNextMessageLength;
|
||||||
|
|
||||||
if( xBytesToStoreMessageLength != ( size_t ) 0 )
|
if( xBytesToStoreMessageLength != ( size_t ) 0 )
|
||||||
{
|
{
|
||||||
|
@ -864,7 +912,8 @@ size_t xOriginalTail, xReceivedLength, xNextMessageLength;
|
||||||
returned to its prior state if the length of the message is too
|
returned to its prior state if the length of the message is too
|
||||||
large for the provided buffer. */
|
large for the provided buffer. */
|
||||||
xOriginalTail = pxStreamBuffer->xTail;
|
xOriginalTail = pxStreamBuffer->xTail;
|
||||||
( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable );
|
( void ) prvReadBytesFromBuffer( pxStreamBuffer, ( uint8_t * ) &xTempNextMessageLength, xBytesToStoreMessageLength, xBytesAvailable );
|
||||||
|
xNextMessageLength = ( size_t ) xTempNextMessageLength;
|
||||||
|
|
||||||
/* Reduce the number of bytes available by the number of bytes just
|
/* Reduce the number of bytes available by the number of bytes just
|
||||||
read out. */
|
read out. */
|
||||||
|
@ -1192,7 +1241,7 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer,
|
||||||
|
|
||||||
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer )
|
uint8_t ucStreamBufferGetStreamBufferType( StreamBufferHandle_t xStreamBuffer )
|
||||||
{
|
{
|
||||||
return ( ( StreamBuffer_t * )xStreamBuffer )->ucFlags | sbFLAGS_IS_MESSAGE_BUFFER;
|
return ( ( StreamBuffer_t * )xStreamBuffer )->ucFlags & sbFLAGS_IS_MESSAGE_BUFFER;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* configUSE_TRACE_FACILITY */
|
#endif /* configUSE_TRACE_FACILITY */
|
||||||
|
|
|
@ -509,7 +509,7 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait, const BaseT
|
||||||
*/
|
*/
|
||||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
|
||||||
|
|
||||||
static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION;
|
static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte ) PRIVILEGED_FUNCTION;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -846,6 +846,8 @@ UBaseType_t x;
|
||||||
uxPriority &= ~portPRIVILEGE_BIT;
|
uxPriority &= ~portPRIVILEGE_BIT;
|
||||||
#endif /* portUSING_MPU_WRAPPERS == 1 */
|
#endif /* portUSING_MPU_WRAPPERS == 1 */
|
||||||
|
|
||||||
|
configASSERT( pcName );
|
||||||
|
|
||||||
/* Avoid dependency on memset() if it is not required. */
|
/* Avoid dependency on memset() if it is not required. */
|
||||||
#if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 )
|
#if( tskSET_NEW_STACKS_TO_KNOWN_VALUE == 1 )
|
||||||
{
|
{
|
||||||
|
@ -1362,11 +1364,30 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB )
|
||||||
else if( pxStateList == &xSuspendedTaskList )
|
else if( pxStateList == &xSuspendedTaskList )
|
||||||
{
|
{
|
||||||
/* The task being queried is referenced from the suspended
|
/* The task being queried is referenced from the suspended
|
||||||
list. Is it genuinely suspended or is it block
|
list. Is it genuinely suspended or is it blocked
|
||||||
indefinitely? */
|
indefinitely? */
|
||||||
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL )
|
if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) == NULL )
|
||||||
{
|
{
|
||||||
eReturn = eSuspended;
|
#if( configUSE_TASK_NOTIFICATIONS == 1 )
|
||||||
|
{
|
||||||
|
/* The task does not appear on the event list item of
|
||||||
|
and of the RTOS objects, but could still be in the
|
||||||
|
blocked state if it is waiting on its notification
|
||||||
|
rather than waiting on an object. */
|
||||||
|
if( pxTCB->ucNotifyState == taskWAITING_NOTIFICATION )
|
||||||
|
{
|
||||||
|
eReturn = eBlocked;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eReturn = eSuspended;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
eReturn = eSuspended;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1982,7 +2003,7 @@ BaseType_t xReturn;
|
||||||
|
|
||||||
xNextTaskUnblockTime = portMAX_DELAY;
|
xNextTaskUnblockTime = portMAX_DELAY;
|
||||||
xSchedulerRunning = pdTRUE;
|
xSchedulerRunning = pdTRUE;
|
||||||
xTickCount = ( TickType_t ) 0U;
|
xTickCount = ( TickType_t ) configINITIAL_TICK_COUNT;
|
||||||
|
|
||||||
/* If configGENERATE_RUN_TIME_STATS is defined then the following
|
/* If configGENERATE_RUN_TIME_STATS is defined then the following
|
||||||
macro must be defined to configure the timer/counter used to generate
|
macro must be defined to configure the timer/counter used to generate
|
||||||
|
@ -1992,6 +2013,8 @@ BaseType_t xReturn;
|
||||||
FreeRTOSConfig.h file. */
|
FreeRTOSConfig.h file. */
|
||||||
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();
|
portCONFIGURE_TIMER_FOR_RUN_TIME_STATS();
|
||||||
|
|
||||||
|
traceTASK_SWITCHED_IN();
|
||||||
|
|
||||||
/* Setting up the timer tick is hardware specific and thus in the
|
/* Setting up the timer tick is hardware specific and thus in the
|
||||||
portable interface. */
|
portable interface. */
|
||||||
if( xPortStartScheduler() != pdFALSE )
|
if( xPortStartScheduler() != pdFALSE )
|
||||||
|
@ -2778,7 +2801,9 @@ BaseType_t xSwitchRequired = pdFALSE;
|
||||||
/* Save the hook function in the TCB. A critical section is required as
|
/* Save the hook function in the TCB. A critical section is required as
|
||||||
the value can be accessed from an interrupt. */
|
the value can be accessed from an interrupt. */
|
||||||
taskENTER_CRITICAL();
|
taskENTER_CRITICAL();
|
||||||
|
{
|
||||||
xTCB->pxTaskTag = pxHookFunction;
|
xTCB->pxTaskTag = pxHookFunction;
|
||||||
|
}
|
||||||
taskEXIT_CRITICAL();
|
taskEXIT_CRITICAL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3474,7 +3499,7 @@ static void prvCheckTasksWaitingTermination( void )
|
||||||
{
|
{
|
||||||
TCB_t *pxTCB;
|
TCB_t *pxTCB;
|
||||||
|
|
||||||
/* uxDeletedTasksWaitingCleanUp is used to prevent vTaskSuspendAll()
|
/* uxDeletedTasksWaitingCleanUp is used to prevent taskENTER_CRITICAL()
|
||||||
being called too often in the idle task. */
|
being called too often in the idle task. */
|
||||||
while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )
|
while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )
|
||||||
{
|
{
|
||||||
|
@ -3625,7 +3650,7 @@ static void prvCheckTasksWaitingTermination( void )
|
||||||
|
|
||||||
#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
|
#if ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) )
|
||||||
|
|
||||||
static uint16_t prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte )
|
static configSTACK_DEPTH_TYPE prvTaskCheckFreeStackSpace( const uint8_t * pucStackByte )
|
||||||
{
|
{
|
||||||
uint32_t ulCount = 0U;
|
uint32_t ulCount = 0U;
|
||||||
|
|
||||||
|
@ -3637,7 +3662,7 @@ static void prvCheckTasksWaitingTermination( void )
|
||||||
|
|
||||||
ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */
|
ulCount /= ( uint32_t ) sizeof( StackType_t ); /*lint !e961 Casting is not redundant on smaller architectures. */
|
||||||
|
|
||||||
return ( uint16_t ) ulCount;
|
return ( configSTACK_DEPTH_TYPE ) ulCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */
|
#endif /* ( ( configUSE_TRACE_FACILITY == 1 ) || ( INCLUDE_uxTaskGetStackHighWaterMark == 1 ) ) */
|
||||||
|
@ -4766,13 +4791,11 @@ TickType_t uxReturn;
|
||||||
{
|
{
|
||||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
/* Mark that a yield is pending in case the user is not
|
||||||
/* Mark that a yield is pending in case the user is not
|
using the "xHigherPriorityTaskWoken" parameter to an ISR
|
||||||
using the "xHigherPriorityTaskWoken" parameter to an ISR
|
safe FreeRTOS function. */
|
||||||
safe FreeRTOS function. */
|
xYieldPending = pdTRUE;
|
||||||
xYieldPending = pdTRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -4856,13 +4879,11 @@ TickType_t uxReturn;
|
||||||
{
|
{
|
||||||
*pxHigherPriorityTaskWoken = pdTRUE;
|
*pxHigherPriorityTaskWoken = pdTRUE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
/* Mark that a yield is pending in case the user is not
|
||||||
/* Mark that a yield is pending in case the user is not
|
using the "xHigherPriorityTaskWoken" parameter in an ISR
|
||||||
using the "xHigherPriorityTaskWoken" parameter in an ISR
|
safe FreeRTOS function. */
|
||||||
safe FreeRTOS function. */
|
xYieldPending = pdTRUE;
|
||||||
xYieldPending = pdTRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
10
bootloader/c_types.h
Normal file
10
bootloader/c_types.h
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
/* rboot type definitions */
|
||||||
|
|
||||||
|
|
||||||
|
typedef int int32;
|
||||||
|
typedef unsigned short uint16;
|
||||||
|
typedef unsigned int uint32;
|
||||||
|
typedef unsigned char uint8;
|
||||||
|
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
|
@ -1 +1 @@
|
||||||
Subproject commit 30afbaa777e00abf9d7d469fb3345f118c4975c1
|
Subproject commit 3b067a8686a07474c5f722953d3b2f0e71db681f
|
|
@ -174,25 +174,32 @@ void IRAM sdk_user_start(void) {
|
||||||
}
|
}
|
||||||
switch (buf8[3] >> 4) {
|
switch (buf8[3] >> 4) {
|
||||||
case 0x0: // 4 Mbit (512 KByte)
|
case 0x0: // 4 Mbit (512 KByte)
|
||||||
flash_sectors = 128;
|
flash_size = 524288;
|
||||||
break;
|
break;
|
||||||
case 0x1: // 2 Mbit (256 Kbyte)
|
case 0x1: // 2 Mbit (256 Kbyte)
|
||||||
flash_sectors = 64;
|
flash_size = 262144;
|
||||||
break;
|
break;
|
||||||
case 0x2: // 8 Mbit (1 Mbyte)
|
case 0x2: // 8 Mbit (1 Mbyte)
|
||||||
flash_sectors = 256;
|
flash_size = 1048576;
|
||||||
break;
|
break;
|
||||||
case 0x3: // 16 Mbit (2 Mbyte)
|
case 0x3: // 16 Mbit (2 Mbyte)
|
||||||
flash_sectors = 512;
|
case 0x5: // 16 Mbit (2 Mbyte)
|
||||||
|
flash_size = 2097152;
|
||||||
break;
|
break;
|
||||||
case 0x4: // 32 Mbit (4 Mbyte)
|
case 0x4: // 32 Mbit (4 Mbyte)
|
||||||
flash_sectors = 1024;
|
case 0x6: // 32 Mbit (4 Mbyte)
|
||||||
|
flash_size = 4194304;
|
||||||
|
break;
|
||||||
|
case 0x8: // 64 Mbit (8 Mbyte)
|
||||||
|
flash_size = 8388608;
|
||||||
|
break;
|
||||||
|
case 0x9: // 128 Mbit (16 Mbyte)
|
||||||
|
flash_size = 16777216;
|
||||||
break;
|
break;
|
||||||
default: // Invalid -- Assume 4 Mbit (512 KByte)
|
default: // Invalid -- Assume 4 Mbit (512 KByte)
|
||||||
flash_sectors = 128;
|
flash_size = 524288;
|
||||||
}
|
}
|
||||||
//FIXME: we should probably calculate flash_sectors by starting with flash_size and dividing by sdk_flashchip.sector_size instead of vice-versa.
|
flash_sectors = flash_size / sdk_flashchip.sector_size;
|
||||||
flash_size = flash_sectors * 4096;
|
|
||||||
sdk_flashchip.chip_size = flash_size;
|
sdk_flashchip.chip_size = flash_size;
|
||||||
set_spi0_divisor(flash_speed_divisor);
|
set_spi0_divisor(flash_speed_divisor);
|
||||||
sdk_SPIRead(flash_size - 4096, buf32, BOOT_INFO_SIZE);
|
sdk_SPIRead(flash_size - 4096, buf32, BOOT_INFO_SIZE);
|
||||||
|
@ -431,8 +438,6 @@ static __attribute__((noinline)) void user_start_phase2(void) {
|
||||||
memcpy(&phy_info, &default_phy_info, sizeof(sdk_phy_info_t));
|
memcpy(&phy_info, &default_phy_info, sizeof(sdk_phy_info_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disable default buffering on stdout
|
|
||||||
setbuf(stdout, NULL);
|
|
||||||
// Wait for UARTs to finish sending anything in their queues.
|
// Wait for UARTs to finish sending anything in their queues.
|
||||||
uart_flush_txfifo(0);
|
uart_flush_txfifo(0);
|
||||||
uart_flush_txfifo(1);
|
uart_flush_txfifo(1);
|
||||||
|
|
|
@ -4,22 +4,22 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void *operator new(size_t size)
|
void * __attribute__((weak)) operator new(size_t size)
|
||||||
{
|
{
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *operator new[](size_t size)
|
void * __attribute__((weak)) operator new[](size_t size)
|
||||||
{
|
{
|
||||||
return malloc(size);
|
return malloc(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete(void * ptr)
|
void __attribute__((weak)) operator delete(void * ptr)
|
||||||
{
|
{
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator delete[](void * ptr)
|
void __attribute__((weak)) operator delete[](void * ptr)
|
||||||
{
|
{
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ struct GPIO_REGS {
|
||||||
uint32_t volatile STATUS_SET; // 0x20
|
uint32_t volatile STATUS_SET; // 0x20
|
||||||
uint32_t volatile STATUS_CLEAR; // 0x24
|
uint32_t volatile STATUS_CLEAR; // 0x24
|
||||||
uint32_t volatile CONF[16]; // 0x28 - 0x64
|
uint32_t volatile CONF[16]; // 0x28 - 0x64
|
||||||
uint32_t volatile PWM; // 0x68
|
uint32_t volatile DSM; // 0x68
|
||||||
uint32_t volatile RTC_CALIB; // 0x6c
|
uint32_t volatile RTC_CALIB; // 0x6c
|
||||||
uint32_t volatile RTC_CALIB_RESULT; // 0x70
|
uint32_t volatile RTC_CALIB_RESULT; // 0x70
|
||||||
};
|
};
|
||||||
|
@ -117,9 +117,9 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size");
|
||||||
* GPIO_CONF_OPEN_DRAIN does not appear to work on all pins.
|
* GPIO_CONF_OPEN_DRAIN does not appear to work on all pins.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* GPIO_CONF_SOURCE_PWM (boolean)
|
* GPIO_CONF_SOURCE_DSM (boolean)
|
||||||
* When set, GPIO pin output will be connected to the sigma-delta PWM
|
* When set, GPIO pin output will be connected to the sigma-delta
|
||||||
* generator (controlled by the GPIO.PWM register). When cleared, pin
|
* generator (controlled by the GPIO.DSM register). When cleared, pin
|
||||||
* output will function as a normal GPIO output (controlled by the
|
* output will function as a normal GPIO output (controlled by the
|
||||||
* GPIO.OUT* registers).
|
* GPIO.OUT* registers).
|
||||||
*/
|
*/
|
||||||
|
@ -130,7 +130,7 @@ _Static_assert(sizeof(struct GPIO_REGS) == 0x74, "GPIO_REGS is the wrong size");
|
||||||
#define GPIO_CONF_INTTYPE_M 0x00000007
|
#define GPIO_CONF_INTTYPE_M 0x00000007
|
||||||
#define GPIO_CONF_INTTYPE_S 7
|
#define GPIO_CONF_INTTYPE_S 7
|
||||||
#define GPIO_CONF_OPEN_DRAIN BIT(2)
|
#define GPIO_CONF_OPEN_DRAIN BIT(2)
|
||||||
#define GPIO_CONF_SOURCE_PWM BIT(0)
|
#define GPIO_CONF_SOURCE_DSM BIT(0)
|
||||||
|
|
||||||
/* Valid values for the GPIO_CONF_INTTYPE field */
|
/* Valid values for the GPIO_CONF_INTTYPE field */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -142,13 +142,13 @@ typedef enum {
|
||||||
GPIO_INTTYPE_LEVEL_HIGH = 5,
|
GPIO_INTTYPE_LEVEL_HIGH = 5,
|
||||||
} gpio_inttype_t;
|
} gpio_inttype_t;
|
||||||
|
|
||||||
/* Details for PWM register */
|
/* Details for DSM register */
|
||||||
|
|
||||||
#define GPIO_PWM_ENABLE BIT(16)
|
#define GPIO_DSM_ENABLE BIT(16)
|
||||||
#define GPIO_PWM_PRESCALER_M 0x000000ff
|
#define GPIO_DSM_PRESCALER_M 0x000000ff
|
||||||
#define GPIO_PWM_PRESCALER_S 8
|
#define GPIO_DSM_PRESCALER_S 8
|
||||||
#define GPIO_PWM_TARGET_M 0x000000ff
|
#define GPIO_DSM_TARGET_M 0x000000ff
|
||||||
#define GPIO_PWM_TARGET_S 0
|
#define GPIO_DSM_TARGET_S 0
|
||||||
|
|
||||||
/* Details for RTC_CALIB register */
|
/* Details for RTC_CALIB register */
|
||||||
|
|
||||||
|
|
|
@ -160,4 +160,14 @@ static inline UART_Parity uart_get_parity(int uart_num) {
|
||||||
return (UART_Parity)((UART(uart_num).CONF0 & UART_CONF0_PARITY) != 0);
|
return (UART_Parity)((UART(uart_num).CONF0 & UART_CONF0_PARITY) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set uart data bits length to the desired value */
|
||||||
|
static inline void uart_set_byte_length(int uart_num, UART_ByteLength byte_length) {
|
||||||
|
UART(uart_num).CONF0 = SET_FIELD(UART(uart_num).CONF0, UART_CONF0_BYTE_LEN, byte_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns the current data bits length for the UART */
|
||||||
|
static inline UART_ByteLength uart_get_byte_length(int uart_num) {
|
||||||
|
return (UART_ByteLength)(FIELD2VAL(UART_CONF0_BYTE_LEN, UART(uart_num).CONF0));
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _ESP_UART_H */
|
#endif /* _ESP_UART_H */
|
||||||
|
|
|
@ -62,6 +62,13 @@ typedef enum {
|
||||||
UART_PARITY_ODD = 0b1
|
UART_PARITY_ODD = 0b1
|
||||||
} UART_Parity;
|
} UART_Parity;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UART_BYTELENGTH_5 = 0b00,
|
||||||
|
UART_BYTELENGTH_6 = 0b01,
|
||||||
|
UART_BYTELENGTH_7 = 0b10,
|
||||||
|
UART_BYTELENGTH_8 = 0b11,
|
||||||
|
} UART_ByteLength;
|
||||||
|
|
||||||
/* Details for FIFO register */
|
/* Details for FIFO register */
|
||||||
|
|
||||||
#define UART_FIFO_DATA_M 0x000000ff
|
#define UART_FIFO_DATA_M 0x000000ff
|
||||||
|
|
|
@ -303,6 +303,10 @@ void _lock_acquire(_lock_t *lock) {
|
||||||
|
|
||||||
void _lock_acquire_recursive(_lock_t *lock) {
|
void _lock_acquire_recursive(_lock_t *lock) {
|
||||||
if (locks_initialized) {
|
if (locks_initialized) {
|
||||||
|
if (sdk_NMIIrqIsOn) {
|
||||||
|
uart_putc(0, ':');
|
||||||
|
return;
|
||||||
|
}
|
||||||
xSemaphoreTakeRecursive((QueueHandle_t)*lock, portMAX_DELAY);
|
xSemaphoreTakeRecursive((QueueHandle_t)*lock, portMAX_DELAY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -321,6 +325,9 @@ void _lock_release(_lock_t *lock) {
|
||||||
|
|
||||||
void _lock_release_recursive(_lock_t *lock) {
|
void _lock_release_recursive(_lock_t *lock) {
|
||||||
if (locks_initialized) {
|
if (locks_initialized) {
|
||||||
|
if (sdk_NMIIrqIsOn) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
xSemaphoreGiveRecursive((QueueHandle_t)*lock);
|
xSemaphoreGiveRecursive((QueueHandle_t)*lock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -505,6 +505,8 @@ sysparam_status_t sysparam_init(uint32_t base_addr, uint32_t top_addr) {
|
||||||
struct sysparam_context ctx;
|
struct sysparam_context ctx;
|
||||||
uint16_t num_sectors;
|
uint16_t num_sectors;
|
||||||
|
|
||||||
|
_sysparam_info.sem = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
// Make sure we're starting at the beginning of the sector
|
// Make sure we're starting at the beginning of the sector
|
||||||
base_addr -= (base_addr % sdk_flashchip.sector_size);
|
base_addr -= (base_addr % sdk_flashchip.sector_size);
|
||||||
|
|
||||||
|
@ -584,8 +586,6 @@ sysparam_status_t sysparam_init(uint32_t base_addr, uint32_t top_addr) {
|
||||||
_sysparam_info.end_addr = ctx.addr;
|
_sysparam_info.end_addr = ctx.addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
_sysparam_info.sem = xSemaphoreCreateMutex();
|
|
||||||
|
|
||||||
return SYSPARAM_OK;
|
return SYSPARAM_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
examples/dsm_test/Makefile
Normal file
4
examples/dsm_test/Makefile
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
# Simple makefile for simple example
|
||||||
|
PROGRAM=dsm_test
|
||||||
|
EXTRA_COMPONENTS = extras/dsm
|
||||||
|
include ../../common.mk
|
67
examples/dsm_test/dsm_test.c
Normal file
67
examples/dsm_test/dsm_test.c
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
/* Very basic example to test the dsm library
|
||||||
|
* Led intensity from module will change over time.
|
||||||
|
*
|
||||||
|
* Part of esp-open-rtos
|
||||||
|
* Copyright (C) 2018 zaltora (https://github.com/Zaltora)
|
||||||
|
* BSD Licensed as described in the file LICENSE
|
||||||
|
*/
|
||||||
|
#include "espressif/esp_common.h"
|
||||||
|
#include "esp/uart.h"
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "dsm.h"
|
||||||
|
|
||||||
|
#define TEST_WITH_160MHZ (0)
|
||||||
|
#define DSM_PIN (2)
|
||||||
|
|
||||||
|
void task1(void *pvParameters)
|
||||||
|
{
|
||||||
|
uint32_t const init_count = 0;
|
||||||
|
uint32_t count = init_count;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
vTaskDelay(100/portTICK_PERIOD_MS);
|
||||||
|
printf("Target set to %3u, ", count);
|
||||||
|
//Freq = (80,000,000/prescale) * (target / 256) HZ (0 < target < 128)
|
||||||
|
//Freq = (80,000,000/prescale) * ((256 - target) / 256) HZ (128 < target < 256)
|
||||||
|
if (count < 128)
|
||||||
|
{
|
||||||
|
printf("Freqency: %.1f Hz\r\n", (80000000.0/255.0 * (count/ 256.0)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Freqency: %.1f Hz\r\n", 80000000.0/255.0 * ((256.0-count)/ 256.0));
|
||||||
|
}
|
||||||
|
dsm_set_target(count);
|
||||||
|
count++;
|
||||||
|
if (count > UINT8_MAX)
|
||||||
|
count = init_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void user_init(void)
|
||||||
|
{
|
||||||
|
uint8_t pins[1];
|
||||||
|
uart_set_baud(0, 115200);
|
||||||
|
|
||||||
|
#if (TEST_WITH_160MHZ)
|
||||||
|
sdk_system_update_cpu_freq(160);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printf("SDK version:%s\r\n", sdk_system_get_sdk_version());
|
||||||
|
|
||||||
|
pins[0] = DSM_PIN;
|
||||||
|
|
||||||
|
/* register pin to use with DSM */
|
||||||
|
dsm_init(1, pins);
|
||||||
|
/* Set prescale to FF to get a proper signal */
|
||||||
|
dsm_set_prescale(0xFF);
|
||||||
|
/* Target initial */
|
||||||
|
dsm_set_target(0);
|
||||||
|
/* start dsm to pin */
|
||||||
|
dsm_start();
|
||||||
|
|
||||||
|
printf("dsm start\r\n");
|
||||||
|
|
||||||
|
xTaskCreate(task1, "tsk1", 256, NULL, 2, NULL);
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#define CS_GPIO_PIN 2
|
#define CS_GPIO_PIN 2
|
||||||
#define TEST_FILENAME "/test_loooong_filename.txt"
|
#define TEST_FILENAME "/test_loooong_filename.txt"
|
||||||
|
#define TEST_DIRECTORYNAME "my_directory"
|
||||||
#define TEST_CONTENTS "Hello! It's FatFs on esp8266 with ESP Open RTOS!"
|
#define TEST_CONTENTS "Hello! It's FatFs on esp8266 with ESP Open RTOS!"
|
||||||
#define READBUF_SIZE 256
|
#define READBUF_SIZE 256
|
||||||
#define DELAY_MS 3000
|
#define DELAY_MS 3000
|
||||||
|
@ -69,6 +70,19 @@ void check_fatfs()
|
||||||
if (failed(f_chdrive(vol)))
|
if (failed(f_chdrive(vol)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Create a directory if it not exists
|
||||||
|
FILINFO info;
|
||||||
|
if (failed(f_stat(TEST_DIRECTORYNAME, &info)) && info.fattrib & AM_DIR)
|
||||||
|
{
|
||||||
|
printf("f_mkdir (\"%s\")\n", TEST_DIRECTORYNAME);
|
||||||
|
if (failed(f_mkdir(TEST_DIRECTORYNAME)))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\"%s\" directory already exists\n", TEST_DIRECTORYNAME);
|
||||||
|
}
|
||||||
|
|
||||||
FIL f;
|
FIL f;
|
||||||
// Create test file
|
// Create test file
|
||||||
printf("f_open(&f, \"%s\", FA_WRITE | FA_CREATE_ALWAYS)", TEST_FILENAME);
|
printf("f_open(&f, \"%s\", FA_WRITE | FA_CREATE_ALWAYS)", TEST_FILENAME);
|
||||||
|
|
9
extras/dsm/component.mk
Normal file
9
extras/dsm/component.mk
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Component makefile for extras/dsm
|
||||||
|
|
||||||
|
INC_DIRS += $(ROOT)extras/dsm
|
||||||
|
|
||||||
|
# args for passing into compile rule generation
|
||||||
|
extras/dsm_INC_DIR = $(ROOT)extras/dsm
|
||||||
|
extras/dsm_SRC_DIR = $(ROOT)extras/dsm
|
||||||
|
|
||||||
|
$(eval $(call component_compile_rules,extras/dsm))
|
111
extras/dsm/dsm.c
Normal file
111
extras/dsm/dsm.c
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/* Implementation of Delta-Sigma modulator support.
|
||||||
|
*
|
||||||
|
* Part of esp-open-rtos
|
||||||
|
* Copyright (C) 2018 ourairquality (https://github.com/ourairquality)
|
||||||
|
* Copyright (C) 2018 Zaltora (https://github.com/Zaltora)
|
||||||
|
* BSD Licensed as described in the file LICENSE
|
||||||
|
*/
|
||||||
|
#include "dsm.h"
|
||||||
|
|
||||||
|
#include <espressif/esp_common.h>
|
||||||
|
#include <esp8266.h>
|
||||||
|
|
||||||
|
|
||||||
|
#if (DSM_DEBUG)
|
||||||
|
#define debug(fmt, ...) printf("%s: " fmt "\n", "DSM", ## __VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define debug(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct dsmInfoDefinition
|
||||||
|
{
|
||||||
|
uint8_t running;
|
||||||
|
uint8_t preScale;
|
||||||
|
uint8_t target;
|
||||||
|
bool output;
|
||||||
|
|
||||||
|
/* private */
|
||||||
|
uint8_t usedPins;
|
||||||
|
uint8_t pins[8];
|
||||||
|
} DSMInfo;
|
||||||
|
|
||||||
|
static DSMInfo dsmInfo;
|
||||||
|
|
||||||
|
void dsm_init(uint8_t npins, const uint8_t* pins)
|
||||||
|
{
|
||||||
|
/* Assert number of pins is correct */
|
||||||
|
if (npins > MAX_DSM_PINS)
|
||||||
|
{
|
||||||
|
debug("Incorrect number of DSM pins (%d)\n", npins);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save pins information */
|
||||||
|
dsmInfo.usedPins = npins;
|
||||||
|
|
||||||
|
for (uint8_t i = 0 ; i < npins; ++i)
|
||||||
|
{
|
||||||
|
dsmInfo.pins[i] = pins[i];
|
||||||
|
/* configure GPIOs */
|
||||||
|
gpio_enable(pins[i], GPIO_OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set output to LOW */
|
||||||
|
dsm_stop();
|
||||||
|
|
||||||
|
/* Flag not running */
|
||||||
|
dsmInfo.running = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dsm_set_prescale(uint8_t prescale)
|
||||||
|
{
|
||||||
|
//TODO: Add a freq/prescale converter
|
||||||
|
dsmInfo.preScale = prescale;
|
||||||
|
debug("Set Prescale: %u",dsmInfo.preScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dsm_set_target(uint8_t target)
|
||||||
|
{
|
||||||
|
dsmInfo.target = target;
|
||||||
|
if (target == 0 || target == UINT8_MAX)
|
||||||
|
{
|
||||||
|
dsmInfo.output = (target == UINT8_MAX);
|
||||||
|
}
|
||||||
|
debug("Duty set at %u",dsmInfo.target);
|
||||||
|
if (dsmInfo.running)
|
||||||
|
{
|
||||||
|
dsm_start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dsm_start()
|
||||||
|
{
|
||||||
|
if (dsmInfo.target > 0 && dsmInfo.target < UINT8_MAX)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < dsmInfo.usedPins; ++i)
|
||||||
|
{
|
||||||
|
SET_MASK_BITS(GPIO.CONF[dsmInfo.pins[i]], GPIO_CONF_SOURCE_DSM);
|
||||||
|
}
|
||||||
|
GPIO.DSM = GPIO_DSM_ENABLE | (dsmInfo.preScale << 8) | dsmInfo.target;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < dsmInfo.usedPins; ++i)
|
||||||
|
{
|
||||||
|
gpio_write(dsmInfo.pins[i], dsmInfo.output );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debug("start");
|
||||||
|
dsmInfo.running = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dsm_stop()
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < dsmInfo.usedPins; ++i)
|
||||||
|
{
|
||||||
|
CLEAR_MASK_BITS(GPIO.CONF[dsmInfo.pins[i]], GPIO_CONF_SOURCE_DSM);
|
||||||
|
gpio_write(dsmInfo.pins[i], false);
|
||||||
|
}
|
||||||
|
debug("stop");
|
||||||
|
dsmInfo.running = 0;
|
||||||
|
}
|
36
extras/dsm/dsm.h
Normal file
36
extras/dsm/dsm.h
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
/* Implementation of Delta-Sigma modulator support.
|
||||||
|
*
|
||||||
|
* Part of esp-open-rtos
|
||||||
|
* Copyright (C) 2018 ourairquality (https://github.com/ourairquality)
|
||||||
|
* Copyright (C) 2018 Zaltora (https://github.com/Zaltora)
|
||||||
|
* BSD Licensed as described in the file LICENSE
|
||||||
|
*/
|
||||||
|
#ifndef EXTRAS_DSM_H_
|
||||||
|
#define EXTRAS_DSM_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define MAX_DSM_PINS (8)
|
||||||
|
#define DSM_DEBUG (0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Freq = (80,000,000/prescale) * (target / 256) HZ (0 < target < 128)
|
||||||
|
* Freq = (80,000,000/prescale) * ((256 - target) / 256) HZ (128 < target < 256)
|
||||||
|
*/
|
||||||
|
|
||||||
|
void dsm_init(uint8_t npins, const uint8_t* pins);
|
||||||
|
void dsm_set_prescale(uint8_t prescale);
|
||||||
|
void dsm_set_target(uint8_t target);
|
||||||
|
|
||||||
|
void dsm_start();
|
||||||
|
void dsm_stop();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* EXTRAS_DSM_H_ */
|
|
@ -32,6 +32,7 @@
|
||||||
//#define I2C_DEBUG true
|
//#define I2C_DEBUG true
|
||||||
|
|
||||||
#ifdef I2C_DEBUG
|
#ifdef I2C_DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
#define debug(fmt, ...) printf("%s: " fmt "\n", "I2C", ## __VA_ARGS__)
|
#define debug(fmt, ...) printf("%s: " fmt "\n", "I2C", ## __VA_ARGS__)
|
||||||
#else
|
#else
|
||||||
#define debug(fmt, ...)
|
#define debug(fmt, ...)
|
||||||
|
@ -66,7 +67,7 @@ typedef struct i2c_bus_description
|
||||||
bool started;
|
bool started;
|
||||||
bool flag;
|
bool flag;
|
||||||
bool force;
|
bool force;
|
||||||
uint32_t clk_stretch;
|
TickType_t clk_stretch;
|
||||||
} i2c_bus_description_t;
|
} i2c_bus_description_t;
|
||||||
|
|
||||||
static i2c_bus_description_t i2c_bus[I2C_MAX_BUS];
|
static i2c_bus_description_t i2c_bus[I2C_MAX_BUS];
|
||||||
|
@ -183,7 +184,7 @@ int i2c_set_frequency_hz(uint8_t bus, uint32_t freq)
|
||||||
return not_ok ? -EINVAL : 0;
|
return not_ok ? -EINVAL : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void i2c_set_clock_stretch(uint8_t bus, uint32_t clk_stretch)
|
void i2c_set_clock_stretch(uint8_t bus, TickType_t clk_stretch)
|
||||||
{
|
{
|
||||||
i2c_bus[bus].clk_stretch = clk_stretch;
|
i2c_bus[bus].clk_stretch = clk_stretch;
|
||||||
}
|
}
|
||||||
|
@ -235,13 +236,46 @@ static inline void clear_sda(uint8_t bus)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void set_scl(uint8_t bus)
|
#define I2C_CLK_STRETCH_SPIN 1024
|
||||||
|
|
||||||
|
static void set_scl(uint8_t bus)
|
||||||
{
|
{
|
||||||
#if I2C_USE_GPIO16 == 1
|
#if I2C_USE_GPIO16 == 1
|
||||||
gpio_write(i2c_bus[bus].g_scl_pin, 1);
|
gpio_write(i2c_bus[bus].g_scl_pin, 1);
|
||||||
#else
|
#else
|
||||||
GPIO.OUT_SET = i2c_bus[bus].g_scl_mask;
|
GPIO.OUT_SET = i2c_bus[bus].g_scl_mask;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Clock stretching.
|
||||||
|
|
||||||
|
// Spin sampling frequently.
|
||||||
|
uint32_t clk_stretch_spin = I2C_CLK_STRETCH_SPIN;
|
||||||
|
do {
|
||||||
|
if (read_scl(bus)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
clk_stretch_spin--;
|
||||||
|
} while (clk_stretch_spin);
|
||||||
|
|
||||||
|
// Fall back to a longer wait, sampling less frequently.
|
||||||
|
TickType_t clk_stretch = i2c_bus[bus].clk_stretch;
|
||||||
|
TickType_t start = xTaskGetTickCount();
|
||||||
|
|
||||||
|
do {
|
||||||
|
vTaskDelay(20 / portTICK_PERIOD_MS);
|
||||||
|
|
||||||
|
if (read_scl(bus)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
TickType_t elapsed = xTaskGetTickCount() - start;
|
||||||
|
if (elapsed > clk_stretch) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (1);
|
||||||
|
|
||||||
|
debug("bus %u clock stretch timeout", bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void set_sda(uint8_t bus)
|
static inline void set_sda(uint8_t bus)
|
||||||
|
@ -265,10 +299,7 @@ void i2c_start(uint8_t bus)
|
||||||
// Set SDA to 1
|
// Set SDA to 1
|
||||||
set_sda(bus);
|
set_sda(bus);
|
||||||
i2c_delay(bus);
|
i2c_delay(bus);
|
||||||
uint32_t clk_stretch = i2c_bus[bus].clk_stretch;
|
|
||||||
set_scl(bus);
|
set_scl(bus);
|
||||||
while (read_scl(bus) == 0 && clk_stretch--)
|
|
||||||
;
|
|
||||||
// Repeated start setup time, minimum 4.7us
|
// Repeated start setup time, minimum 4.7us
|
||||||
i2c_delay(bus);
|
i2c_delay(bus);
|
||||||
}
|
}
|
||||||
|
@ -286,14 +317,10 @@ void i2c_start(uint8_t bus)
|
||||||
// Output stop condition
|
// Output stop condition
|
||||||
bool i2c_stop(uint8_t bus)
|
bool i2c_stop(uint8_t bus)
|
||||||
{
|
{
|
||||||
uint32_t clk_stretch = i2c_bus[bus].clk_stretch;
|
|
||||||
// Set SDA to 0
|
// Set SDA to 0
|
||||||
clear_sda(bus);
|
clear_sda(bus);
|
||||||
i2c_delay(bus);
|
i2c_delay(bus);
|
||||||
// Clock stretching
|
|
||||||
set_scl(bus);
|
set_scl(bus);
|
||||||
while (read_scl(bus) == 0 && clk_stretch--)
|
|
||||||
;
|
|
||||||
// Stop bit setup time, minimum 4us
|
// Stop bit setup time, minimum 4us
|
||||||
i2c_delay(bus);
|
i2c_delay(bus);
|
||||||
// SCL is high, set SDA from 0 to 1
|
// SCL is high, set SDA from 0 to 1
|
||||||
|
@ -315,17 +342,13 @@ bool i2c_stop(uint8_t bus)
|
||||||
// Write a bit to I2C bus
|
// Write a bit to I2C bus
|
||||||
static void i2c_write_bit(uint8_t bus, bool bit)
|
static void i2c_write_bit(uint8_t bus, bool bit)
|
||||||
{
|
{
|
||||||
uint32_t clk_stretch = i2c_bus[bus].clk_stretch;
|
|
||||||
if (bit) {
|
if (bit) {
|
||||||
set_sda(bus);
|
set_sda(bus);
|
||||||
} else {
|
} else {
|
||||||
clear_sda(bus);
|
clear_sda(bus);
|
||||||
}
|
}
|
||||||
i2c_delay(bus);
|
i2c_delay(bus);
|
||||||
// Clock stretching
|
|
||||||
set_scl(bus);
|
set_scl(bus);
|
||||||
while (read_scl(bus) == 0 && clk_stretch--)
|
|
||||||
;
|
|
||||||
// SCL is high, now data is valid
|
// SCL is high, now data is valid
|
||||||
// If SDA is high, check that nobody else is driving SDA
|
// If SDA is high, check that nobody else is driving SDA
|
||||||
if (bit && read_sda(bus) == 0) {
|
if (bit && read_sda(bus) == 0) {
|
||||||
|
@ -338,15 +361,11 @@ static void i2c_write_bit(uint8_t bus, bool bit)
|
||||||
// Read a bit from I2C bus
|
// Read a bit from I2C bus
|
||||||
static bool i2c_read_bit(uint8_t bus)
|
static bool i2c_read_bit(uint8_t bus)
|
||||||
{
|
{
|
||||||
uint32_t clk_stretch = i2c_bus[bus].clk_stretch;
|
|
||||||
bool bit;
|
bool bit;
|
||||||
// Let the slave drive data
|
// Let the slave drive data
|
||||||
set_sda(bus);
|
set_sda(bus);
|
||||||
i2c_delay(bus);
|
i2c_delay(bus);
|
||||||
set_scl(bus);
|
set_scl(bus);
|
||||||
// Clock stretching
|
|
||||||
while (read_scl(bus) == 0 && clk_stretch--)
|
|
||||||
;
|
|
||||||
// SCL is high, now data is valid
|
// SCL is high, now data is valid
|
||||||
bit = read_sda(bus);
|
bit = read_sda(bus);
|
||||||
i2c_delay(bus);
|
i2c_delay(bus);
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
#include <task.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -51,7 +53,8 @@ extern "C" {
|
||||||
#define I2C_USE_GPIO16 0
|
#define I2C_USE_GPIO16 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define I2C_DEFAULT_CLK_STRETCH (10)
|
/* Default clock strech waiting time, 250 msec. */
|
||||||
|
#define I2C_DEFAULT_CLK_STRETCH (250 / portTICK_PERIOD_MS)
|
||||||
|
|
||||||
/* SCL speed settings. 160 MHz sysclk frequency will result in improved
|
/* SCL speed settings. 160 MHz sysclk frequency will result in improved
|
||||||
* timing accuracy. Greater bitrates will have poorer accuracy. 1000K is the
|
* timing accuracy. Greater bitrates will have poorer accuracy. 1000K is the
|
||||||
|
@ -86,7 +89,6 @@ typedef struct i2c_dev
|
||||||
* @param scl_pin SCL pin for I2C
|
* @param scl_pin SCL pin for I2C
|
||||||
* @param sda_pin SDA pin for I2C
|
* @param sda_pin SDA pin for I2C
|
||||||
* @param freq frequency of bus (ex : I2C_FREQ_400K)
|
* @param freq frequency of bus (ex : I2C_FREQ_400K)
|
||||||
* @param clk_stretch I2C clock stretch. I2C_DEFAULT_CLK_STRETCH would be good in most cases
|
|
||||||
* @return Non-zero if error occured
|
* @return Non-zero if error occured
|
||||||
*/
|
*/
|
||||||
int i2c_init(uint8_t bus, uint8_t scl_pin, uint8_t sda_pin, i2c_freq_t freq);
|
int i2c_init(uint8_t bus, uint8_t scl_pin, uint8_t sda_pin, i2c_freq_t freq);
|
||||||
|
@ -97,7 +99,6 @@ int i2c_init(uint8_t bus, uint8_t scl_pin, uint8_t sda_pin, i2c_freq_t freq);
|
||||||
* @param scl_pin SCL pin for I2C
|
* @param scl_pin SCL pin for I2C
|
||||||
* @param sda_pin SDA pin for I2C
|
* @param sda_pin SDA pin for I2C
|
||||||
* @param freq frequency of bus in hertz
|
* @param freq frequency of bus in hertz
|
||||||
* @param clk_stretch I2C clock stretch. I2C_DEFAULT_CLK_STRETCH would be good in most cases
|
|
||||||
* @return Non-zero if error occured
|
* @return Non-zero if error occured
|
||||||
*/
|
*/
|
||||||
int i2c_init_hz(uint8_t bus, uint8_t scl_pin, uint8_t sda_pin, uint32_t freq);
|
int i2c_init_hz(uint8_t bus, uint8_t scl_pin, uint8_t sda_pin, uint32_t freq);
|
||||||
|
@ -119,9 +120,9 @@ int i2c_set_frequency_hz(uint8_t bus, uint32_t freq);
|
||||||
/**
|
/**
|
||||||
* Change clock stretch
|
* Change clock stretch
|
||||||
* @param bus I2C bus
|
* @param bus I2C bus
|
||||||
* @param clk_stretch I2C clock stretch. I2C_DEFAULT_CLK_STRETCH by default
|
* @param clk_stretch I2C clock stretch, in ticks. I2C_DEFAULT_CLK_STRETCH by default
|
||||||
*/
|
*/
|
||||||
void i2c_set_clock_stretch(uint8_t bus, uint32_t clk_stretch);
|
void i2c_set_clock_stretch(uint8_t bus, TickType_t clk_stretch);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a byte to I2C bus.
|
* Write a byte to I2C bus.
|
||||||
|
|
|
@ -26,7 +26,7 @@ OBJS_CRYPTO= aes.o aesni.o arc4.o \
|
||||||
padlock.o pem.o pk.o \
|
padlock.o pem.o pk.o \
|
||||||
pk_wrap.o pkcs12.o pkcs5.o \
|
pk_wrap.o pkcs12.o pkcs5.o \
|
||||||
pkparse.o pkwrite.o platform.o \
|
pkparse.o pkwrite.o platform.o \
|
||||||
ripemd160.o rsa.o sha1.o \
|
ripemd160.o rsa.o rsa_internal.o sha1.o \
|
||||||
sha256.o sha512.o threading.o \
|
sha256.o sha512.o threading.o \
|
||||||
timing.o version.o \
|
timing.o version.o \
|
||||||
version_features.o xtea.o
|
version_features.o xtea.o
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit f2a597fa3dd1c7b15e0fee62f6932b253295803d
|
Subproject commit 1bf6123fca97a9a35c2f403ab0c96495f9580db6
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* TCP/IP or UDP/IP networking functions
|
* TCP/IP or UDP/IP networking functions
|
||||||
* modified for LWIP support on ESP8266
|
* Based on mbedtls/library/net_sockets.c
|
||||||
|
* Modified for LWIP support on ESP8266
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
* Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
|
||||||
* Additions Copyright (C) 2015 Angus Gratton
|
* Additions Copyright (C) 2015 Angus Gratton
|
||||||
|
@ -21,7 +22,6 @@
|
||||||
* This file is part of mbed TLS (https://tls.mbed.org)
|
* This file is part of mbed TLS (https://tls.mbed.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#if !defined(MBEDTLS_CONFIG_FILE)
|
#if !defined(MBEDTLS_CONFIG_FILE)
|
||||||
#include "mbedtls/config.h"
|
#include "mbedtls/config.h"
|
||||||
#else
|
#else
|
||||||
|
@ -30,18 +30,74 @@
|
||||||
|
|
||||||
#if defined(MBEDTLS_NET_C)
|
#if defined(MBEDTLS_NET_C)
|
||||||
|
|
||||||
|
#define ESP_OPEN_RTOS 1
|
||||||
|
#define _SOCKLEN_T_DECLARED 1
|
||||||
|
|
||||||
|
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
|
||||||
|
!defined(__APPLE__) && !defined(_WIN32) && !defined(ESP_OPEN_RTOS)
|
||||||
|
#error "This module only works on Unix and Windows, see MBEDTLS_NET_C in config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PLATFORM_C)
|
||||||
|
#include "mbedtls/platform.h"
|
||||||
|
#else
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mbedtls/net_sockets.h"
|
#include "mbedtls/net_sockets.h"
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#if (defined(_WIN32) || defined(_WIN32_WCE)) && !defined(EFIX64) && \
|
||||||
|
!defined(EFI32)
|
||||||
|
|
||||||
|
#ifdef _WIN32_WINNT
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#endif
|
||||||
|
/* Enables getaddrinfo() & Co */
|
||||||
|
#define _WIN32_WINNT 0x0501
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#if defined(_WIN32_WCE)
|
||||||
|
#pragma comment( lib, "ws2.lib" )
|
||||||
|
#else
|
||||||
|
#pragma comment( lib, "ws2_32.lib" )
|
||||||
|
#endif
|
||||||
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
|
#define read(fd,buf,len) recv( fd, (char*)( buf ), (int)( len ), 0 )
|
||||||
|
#define write(fd,buf,len) send( fd, (char*)( buf ), (int)( len ), 0 )
|
||||||
|
#define close(fd) closesocket(fd)
|
||||||
|
|
||||||
|
static int wsa_init_done = 0;
|
||||||
|
|
||||||
|
#else /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
//#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
|
||||||
|
|
||||||
|
/* Some MS functions want int and MSVC warns if we pass size_t,
|
||||||
|
* but the standard functions use socklen_t, so cast only for MSVC */
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define MSVC_INT_CAST (int)
|
||||||
|
#else
|
||||||
|
#define MSVC_INT_CAST
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -65,6 +121,9 @@ static int net_prepare( void )
|
||||||
wsa_init_done = 1;
|
wsa_init_done = 1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
#if !defined(EFIX64) && !defined(EFI32) && !defined(ESP_OPEN_RTOS)
|
||||||
|
signal( SIGPIPE, SIG_IGN );
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
@ -80,7 +139,8 @@ void mbedtls_net_init( mbedtls_net_context *ctx )
|
||||||
/*
|
/*
|
||||||
* Initiate a TCP connection with host:port and the given protocol
|
* Initiate a TCP connection with host:port and the given protocol
|
||||||
*/
|
*/
|
||||||
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char *port, int proto )
|
int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host,
|
||||||
|
const char *port, int proto )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct addrinfo hints, *addr_list, *cur;
|
struct addrinfo hints, *addr_list, *cur;
|
||||||
|
@ -109,7 +169,11 @@ int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( connect( ctx->fd, cur->ai_addr, cur->ai_addrlen ) == 0 )
|
const struct timeval timeout = { 60, 0 }; /* 60 second timeout */
|
||||||
|
setsockopt( ctx->fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout) );
|
||||||
|
setsockopt( ctx->fd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout) );
|
||||||
|
|
||||||
|
if( connect( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) == 0 )
|
||||||
{
|
{
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -130,14 +194,7 @@ int mbedtls_net_connect( mbedtls_net_context *ctx, const char *host, const char
|
||||||
int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
|
int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char *port, int proto )
|
||||||
{
|
{
|
||||||
int n, ret;
|
int n, ret;
|
||||||
struct addrinfo *addr_list, *cur;
|
struct addrinfo hints, *addr_list, *cur;
|
||||||
|
|
||||||
/* Only request desired protocol */
|
|
||||||
const struct addrinfo hints = {
|
|
||||||
.ai_family = AF_UNSPEC,
|
|
||||||
.ai_socktype = (proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM),
|
|
||||||
.ai_protocol = (proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP),
|
|
||||||
};
|
|
||||||
|
|
||||||
struct sockaddr_in sockaddr_ipaddr_any = {
|
struct sockaddr_in sockaddr_ipaddr_any = {
|
||||||
.sin_len = sizeof(struct sockaddr_in),
|
.sin_len = sizeof(struct sockaddr_in),
|
||||||
|
@ -148,8 +205,8 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char
|
||||||
|
|
||||||
struct addrinfo all_interfaces_addr = {
|
struct addrinfo all_interfaces_addr = {
|
||||||
.ai_family = AF_INET,
|
.ai_family = AF_INET,
|
||||||
.ai_socktype = hints.ai_socktype,
|
.ai_socktype = (proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM),
|
||||||
.ai_protocol = hints.ai_protocol,
|
.ai_protocol = (proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP),
|
||||||
.ai_addrlen = sizeof(struct sockaddr_in),
|
.ai_addrlen = sizeof(struct sockaddr_in),
|
||||||
.ai_addr = (struct sockaddr *)&sockaddr_ipaddr_any,
|
.ai_addr = (struct sockaddr *)&sockaddr_ipaddr_any,
|
||||||
};
|
};
|
||||||
|
@ -157,14 +214,22 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char
|
||||||
if( ( ret = net_prepare() ) != 0 )
|
if( ( ret = net_prepare() ) != 0 )
|
||||||
return( ret );
|
return( ret );
|
||||||
|
|
||||||
if(bind_ip == NULL) {
|
/* Bind to IPv6 and/or IPv4, but only in the desired protocol */
|
||||||
|
memset( &hints, 0, sizeof( hints ) );
|
||||||
|
hints.ai_family = AF_UNSPEC;
|
||||||
|
hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM : SOCK_STREAM;
|
||||||
|
hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP : IPPROTO_TCP;
|
||||||
|
if( bind_ip == NULL )
|
||||||
|
hints.ai_flags = AI_PASSIVE;
|
||||||
|
|
||||||
|
if( bind_ip == NULL ) {
|
||||||
/* mbedTLS docs specify bind_ip == NULL means all interfaces, but lwip getaddrinfo() assumes NULL
|
/* mbedTLS docs specify bind_ip == NULL means all interfaces, but lwip getaddrinfo() assumes NULL
|
||||||
means localhost. So we swap in a precreated IPADDR_ANY addrinfo result here. */
|
means localhost. So we swap in a precreated IPADDR_ANY addrinfo result here. */
|
||||||
addr_list = &all_interfaces_addr;
|
addr_list = &all_interfaces_addr;
|
||||||
}
|
}
|
||||||
else if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 ) {
|
else
|
||||||
|
if( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 )
|
||||||
return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
|
return( MBEDTLS_ERR_NET_UNKNOWN_HOST );
|
||||||
}
|
|
||||||
|
|
||||||
/* Try the sockaddrs until a binding succeeds */
|
/* Try the sockaddrs until a binding succeeds */
|
||||||
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
|
ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
|
||||||
|
@ -187,7 +252,7 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( bind( ctx->fd, cur->ai_addr, cur->ai_addrlen ) != 0 )
|
if( bind( ctx->fd, cur->ai_addr, MSVC_INT_CAST cur->ai_addrlen ) != 0 )
|
||||||
{
|
{
|
||||||
close( ctx->fd );
|
close( ctx->fd );
|
||||||
ret = MBEDTLS_ERR_NET_BIND_FAILED;
|
ret = MBEDTLS_ERR_NET_BIND_FAILED;
|
||||||
|
@ -205,12 +270,12 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* I we ever get there, it's a success */
|
/* Bind was successful */
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(bind_ip != NULL) {
|
if( bind_ip != NULL ) {
|
||||||
freeaddrinfo( addr_list );
|
freeaddrinfo( addr_list );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,14 +283,18 @@ int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const char
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int socket_errno( const mbedtls_net_context *ctx )
|
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
|
||||||
|
!defined(EFI32)
|
||||||
|
/*
|
||||||
|
* Check if the requested operation would be blocking on a non-blocking socket
|
||||||
|
* and thus 'failed' with a negative return value.
|
||||||
|
*/
|
||||||
|
static int net_would_block( const mbedtls_net_context *ctx )
|
||||||
{
|
{
|
||||||
int sock_errno = 0;
|
((void) ctx);
|
||||||
u32_t optlen = sizeof(sock_errno);
|
return( WSAGetLastError() == WSAEWOULDBLOCK );
|
||||||
lwip_getsockopt(ctx->fd, SOL_SOCKET, SO_ERROR, &sock_errno, &optlen);
|
|
||||||
return sock_errno;
|
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
/*
|
/*
|
||||||
* Check if the requested operation would be blocking on a non-blocking socket
|
* Check if the requested operation would be blocking on a non-blocking socket
|
||||||
* and thus 'failed' with a negative return value.
|
* and thus 'failed' with a negative return value.
|
||||||
|
@ -234,14 +303,18 @@ static int socket_errno( const mbedtls_net_context *ctx )
|
||||||
*/
|
*/
|
||||||
static int net_would_block( const mbedtls_net_context *ctx )
|
static int net_would_block( const mbedtls_net_context *ctx )
|
||||||
{
|
{
|
||||||
|
int err = errno;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Never return 'WOULD BLOCK' on a non-blocking socket
|
* Never return 'WOULD BLOCK' on a non-blocking socket
|
||||||
*/
|
*/
|
||||||
if( ( fcntl( ctx->fd, F_GETFL, 0) & O_NONBLOCK ) != O_NONBLOCK )
|
if( ( fcntl( ctx->fd, F_GETFL, 0) & O_NONBLOCK ) != O_NONBLOCK )
|
||||||
|
{
|
||||||
|
errno = err;
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( errno = err )
|
||||||
switch( socket_errno(ctx) )
|
|
||||||
{
|
{
|
||||||
#if defined EAGAIN
|
#if defined EAGAIN
|
||||||
case EAGAIN:
|
case EAGAIN:
|
||||||
|
@ -253,6 +326,7 @@ static int net_would_block( const mbedtls_net_context *ctx )
|
||||||
}
|
}
|
||||||
return( 0 );
|
return( 0 );
|
||||||
}
|
}
|
||||||
|
#endif /* ( _WIN32 || _WIN32_WCE ) && !EFIX64 && !EFI32 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Accept a connection from a remote client
|
* Accept a connection from a remote client
|
||||||
|
@ -264,14 +338,20 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
|
||||||
int ret;
|
int ret;
|
||||||
int type;
|
int type;
|
||||||
|
|
||||||
struct sockaddr_in client_addr;
|
struct sockaddr_storage client_addr;
|
||||||
|
|
||||||
|
#if defined(__socklen_t_defined) || defined(_SOCKLEN_T) || \
|
||||||
|
defined(_SOCKLEN_T_DECLARED) || defined(__DEFINED_socklen_t)
|
||||||
socklen_t n = (socklen_t) sizeof( client_addr );
|
socklen_t n = (socklen_t) sizeof( client_addr );
|
||||||
socklen_t type_len = (socklen_t) sizeof( type );
|
socklen_t type_len = (socklen_t) sizeof( type );
|
||||||
|
#else
|
||||||
|
int n = (int) sizeof( client_addr );
|
||||||
|
int type_len = (int) sizeof( type );
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Is this a TCP or UDP socket? */
|
/* Is this a TCP or UDP socket? */
|
||||||
if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
|
if( getsockopt( bind_ctx->fd, SOL_SOCKET, SO_TYPE,
|
||||||
(void *) &type, (socklen_t *) &type_len ) != 0 ||
|
(void *) &type, &type_len ) != 0 ||
|
||||||
( type != SOCK_STREAM && type != SOCK_DGRAM ) )
|
( type != SOCK_STREAM && type != SOCK_DGRAM ) )
|
||||||
{
|
{
|
||||||
return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
|
return( MBEDTLS_ERR_NET_ACCEPT_FAILED );
|
||||||
|
@ -288,7 +368,7 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
|
||||||
/* UDP: wait for a message, but keep it in the queue */
|
/* UDP: wait for a message, but keep it in the queue */
|
||||||
char buf[1] = { 0 };
|
char buf[1] = { 0 };
|
||||||
|
|
||||||
ret = recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
|
ret = (int) recvfrom( bind_ctx->fd, buf, sizeof( buf ), MSG_PEEK,
|
||||||
(struct sockaddr *) &client_addr, &n );
|
(struct sockaddr *) &client_addr, &n );
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
@ -313,7 +393,7 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
|
||||||
* then bind a new socket to accept new connections */
|
* then bind a new socket to accept new connections */
|
||||||
if( type != SOCK_STREAM )
|
if( type != SOCK_STREAM )
|
||||||
{
|
{
|
||||||
struct sockaddr_in local_addr;
|
struct sockaddr_storage local_addr;
|
||||||
int one = 1;
|
int one = 1;
|
||||||
|
|
||||||
if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
|
if( connect( bind_ctx->fd, (struct sockaddr *) &client_addr, n ) != 0 )
|
||||||
|
@ -322,10 +402,10 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
|
||||||
client_ctx->fd = bind_ctx->fd;
|
client_ctx->fd = bind_ctx->fd;
|
||||||
bind_ctx->fd = -1; /* In case we exit early */
|
bind_ctx->fd = -1; /* In case we exit early */
|
||||||
|
|
||||||
n = sizeof( struct sockaddr_in );
|
n = sizeof( struct sockaddr_storage );
|
||||||
if( getsockname( client_ctx->fd,
|
if( getsockname( client_ctx->fd,
|
||||||
(struct sockaddr *) &local_addr, &n ) != 0 ||
|
(struct sockaddr *) &local_addr, &n ) != 0 ||
|
||||||
( bind_ctx->fd = (int) socket( AF_INET,
|
( bind_ctx->fd = (int) socket( local_addr.ss_family,
|
||||||
SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
|
SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ||
|
||||||
setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
|
setsockopt( bind_ctx->fd, SOL_SOCKET, SO_REUSEADDR,
|
||||||
(const char *) &one, sizeof( one ) ) != 0 )
|
(const char *) &one, sizeof( one ) ) != 0 )
|
||||||
|
@ -341,6 +421,8 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
|
||||||
|
|
||||||
if( client_ip != NULL )
|
if( client_ip != NULL )
|
||||||
{
|
{
|
||||||
|
if( client_addr.ss_family == AF_INET )
|
||||||
|
{
|
||||||
struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
|
struct sockaddr_in *addr4 = (struct sockaddr_in *) &client_addr;
|
||||||
*ip_len = sizeof( addr4->sin_addr.s_addr );
|
*ip_len = sizeof( addr4->sin_addr.s_addr );
|
||||||
|
|
||||||
|
@ -348,6 +430,19 @@ int mbedtls_net_accept( mbedtls_net_context *bind_ctx,
|
||||||
return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
|
return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
|
||||||
|
|
||||||
memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
|
memcpy( client_ip, &addr4->sin_addr.s_addr, *ip_len );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if LWIP_IPV6
|
||||||
|
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &client_addr;
|
||||||
|
*ip_len = sizeof( addr6->sin6_addr.s6_addr );
|
||||||
|
|
||||||
|
if( buf_size < *ip_len )
|
||||||
|
return( MBEDTLS_ERR_NET_BUFFER_TOO_SMALL );
|
||||||
|
|
||||||
|
memcpy( client_ip, &addr6->sin6_addr.s6_addr, *ip_len);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return( 0 );
|
return( 0 );
|
||||||
|
@ -398,7 +493,9 @@ void mbedtls_net_usleep( unsigned long usec )
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read at most 'len' characters */
|
/*
|
||||||
|
* Read at most 'len' characters
|
||||||
|
*/
|
||||||
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
|
int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -414,13 +511,17 @@ int mbedtls_net_recv( void *ctx, unsigned char *buf, size_t len )
|
||||||
if( net_would_block( ctx ) != 0 )
|
if( net_would_block( ctx ) != 0 )
|
||||||
return( MBEDTLS_ERR_SSL_WANT_READ );
|
return( MBEDTLS_ERR_SSL_WANT_READ );
|
||||||
|
|
||||||
int sock_errno = socket_errno(ctx);
|
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
|
||||||
|
!defined(EFI32)
|
||||||
if( sock_errno == EPIPE || sock_errno == ECONNRESET )
|
if( WSAGetLastError() == WSAECONNRESET )
|
||||||
|
return( MBEDTLS_ERR_NET_CONN_RESET );
|
||||||
|
#else
|
||||||
|
if( errno == EPIPE || errno == ECONNRESET )
|
||||||
return( MBEDTLS_ERR_NET_CONN_RESET );
|
return( MBEDTLS_ERR_NET_CONN_RESET );
|
||||||
|
|
||||||
if( sock_errno == EINTR )
|
if( errno == EINTR )
|
||||||
return( MBEDTLS_ERR_SSL_WANT_READ );
|
return( MBEDTLS_ERR_SSL_WANT_READ );
|
||||||
|
#endif
|
||||||
|
|
||||||
return( MBEDTLS_ERR_NET_RECV_FAILED );
|
return( MBEDTLS_ERR_NET_RECV_FAILED );
|
||||||
}
|
}
|
||||||
|
@ -456,8 +557,14 @@ int mbedtls_net_recv_timeout( void *ctx, unsigned char *buf, size_t len,
|
||||||
|
|
||||||
if( ret < 0 )
|
if( ret < 0 )
|
||||||
{
|
{
|
||||||
|
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
|
||||||
|
!defined(EFI32)
|
||||||
|
if( WSAGetLastError() == WSAEINTR )
|
||||||
|
return( MBEDTLS_ERR_SSL_WANT_READ );
|
||||||
|
#else
|
||||||
if( errno == EINTR )
|
if( errno == EINTR )
|
||||||
return( MBEDTLS_ERR_SSL_WANT_READ );
|
return( MBEDTLS_ERR_SSL_WANT_READ );
|
||||||
|
#endif
|
||||||
|
|
||||||
return( MBEDTLS_ERR_NET_RECV_FAILED );
|
return( MBEDTLS_ERR_NET_RECV_FAILED );
|
||||||
}
|
}
|
||||||
|
@ -484,13 +591,17 @@ int mbedtls_net_send( void *ctx, const unsigned char *buf, size_t len )
|
||||||
if( net_would_block( ctx ) != 0 )
|
if( net_would_block( ctx ) != 0 )
|
||||||
return( MBEDTLS_ERR_SSL_WANT_WRITE );
|
return( MBEDTLS_ERR_SSL_WANT_WRITE );
|
||||||
|
|
||||||
int sock_errno = socket_errno(ctx);
|
#if ( defined(_WIN32) || defined(_WIN32_WCE) ) && !defined(EFIX64) && \
|
||||||
|
!defined(EFI32)
|
||||||
if( sock_errno == EPIPE || sock_errno == ECONNRESET )
|
if( WSAGetLastError() == WSAECONNRESET )
|
||||||
|
return( MBEDTLS_ERR_NET_CONN_RESET );
|
||||||
|
#else
|
||||||
|
if( errno == EPIPE || errno == ECONNRESET )
|
||||||
return( MBEDTLS_ERR_NET_CONN_RESET );
|
return( MBEDTLS_ERR_NET_CONN_RESET );
|
||||||
|
|
||||||
if( sock_errno == EINTR )
|
if( errno == EINTR )
|
||||||
return( MBEDTLS_ERR_SSL_WANT_WRITE );
|
return( MBEDTLS_ERR_SSL_WANT_WRITE );
|
||||||
|
#endif
|
||||||
|
|
||||||
return( MBEDTLS_ERR_NET_SEND_FAILED );
|
return( MBEDTLS_ERR_NET_SEND_FAILED );
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,9 +38,11 @@
|
||||||
#error "LWIP_IGMP needs to be defined in lwipopts.h"
|
#error "LWIP_IGMP needs to be defined in lwipopts.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if MDNS_RESPONDER_DEBUGGING
|
||||||
#define qDebugLog // Log activity generally
|
#define qDebugLog // Log activity generally
|
||||||
#define qLogIncoming // Log all arriving multicast packets
|
#define qLogIncoming // Log all arriving multicast packets
|
||||||
#define qLogAllTraffic // Log and decode all mDNS packets
|
#define qLogAllTraffic // Log and decode all mDNS packets
|
||||||
|
#endif
|
||||||
|
|
||||||
//-------------------------------------------------------------------
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -776,9 +778,13 @@ static void mdns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_a
|
||||||
|
|
||||||
// Sanity checks on size
|
// Sanity checks on size
|
||||||
if (plen > MDNS_RESPONDER_REPLY_SIZE) {
|
if (plen > MDNS_RESPONDER_REPLY_SIZE) {
|
||||||
|
#ifdef qDebugLog
|
||||||
printf(">>> mdns_recv: pbuf too big\n");
|
printf(">>> mdns_recv: pbuf too big\n");
|
||||||
|
#endif
|
||||||
} else if (plen < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + 1 + SIZEOF_DNS_ANSWER + 1)) {
|
} else if (plen < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY + 1 + SIZEOF_DNS_ANSWER + 1)) {
|
||||||
|
#ifdef qDebugLog
|
||||||
printf(">>> mdns_recv: pbuf too small\n");
|
printf(">>> mdns_recv: pbuf too small\n");
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
mdns_payload = malloc(plen);
|
mdns_payload = malloc(plen);
|
||||||
if (!mdns_payload) {
|
if (!mdns_payload) {
|
||||||
|
|
|
@ -21,6 +21,11 @@
|
||||||
#define MDNS_RESPONDER_REPLY_SIZE 320
|
#define MDNS_RESPONDER_REPLY_SIZE 320
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MDNS_RESPONDER_DEBUGGING
|
||||||
|
#define MDNS_RESPONDER_DEBUGGING 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Starts the mDNS responder task, call first
|
// Starts the mDNS responder task, call first
|
||||||
void mdns_init();
|
void mdns_init();
|
||||||
|
|
||||||
|
|
|
@ -182,10 +182,6 @@ static uint8_t command(sdio_card_t *card, uint8_t cmd, uint32_t arg)
|
||||||
wait();
|
wait();
|
||||||
spi_transfer(BUS, buf, NULL, 6, SPI_8BIT);
|
spi_transfer(BUS, buf, NULL, 6, SPI_8BIT);
|
||||||
|
|
||||||
// R1b response
|
|
||||||
if (cmd == CMD12 || cmd == CMD28 || cmd == CMD29)
|
|
||||||
spi_read_byte();
|
|
||||||
|
|
||||||
uint8_t res;
|
uint8_t res;
|
||||||
for (uint8_t i = 0; i < MAX_ERR_COUNT; i ++)
|
for (uint8_t i = 0; i < MAX_ERR_COUNT; i ++)
|
||||||
{
|
{
|
||||||
|
@ -193,6 +189,25 @@ static uint8_t command(sdio_card_t *card, uint8_t cmd, uint32_t arg)
|
||||||
if (!(res & BV(R1_BUSY)))
|
if (!(res & BV(R1_BUSY)))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** If the response is a "busy" type (R1B), then there’s some
|
||||||
|
* special handling that needs to be done. The card will
|
||||||
|
* output a continuous stream of zeros, so the end of the BUSY
|
||||||
|
* state is signaled by any nonzero response.
|
||||||
|
*/
|
||||||
|
if (cmd == CMD12 || cmd == CMD28 || cmd == CMD29)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < MAX_ERR_COUNT; i ++)
|
||||||
|
{
|
||||||
|
res = spi_read_byte();
|
||||||
|
if (res != 0)
|
||||||
|
{
|
||||||
|
spi_transfer_8(BUS, 0xFF);
|
||||||
|
return SDIO_ERR_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,16 +409,10 @@ sdio_error_t sdio_write_sectors(sdio_card_t *card, uint32_t sector, uint8_t *src
|
||||||
if (card->type != SDIO_TYPE_SDHC)
|
if (card->type != SDIO_TYPE_SDHC)
|
||||||
sector <<= 9;
|
sector <<= 9;
|
||||||
|
|
||||||
if (count == 1)
|
bool multi = count != 1;
|
||||||
{
|
|
||||||
// single block
|
|
||||||
if (command(card, CMD24, sector))
|
|
||||||
return set_error(card, SDIO_ERR_IO);
|
|
||||||
return set_error(card, write_data_block(card, TOKEN_SINGLE_TRAN, src));
|
|
||||||
}
|
|
||||||
|
|
||||||
// send pre-erase count
|
// send pre-erase count
|
||||||
if ((card->type == SDIO_TYPE_SD1
|
if (multi && (card->type == SDIO_TYPE_SD1
|
||||||
|| card->type == SDIO_TYPE_SD2
|
|| card->type == SDIO_TYPE_SD2
|
||||||
|| card->type == SDIO_TYPE_SDHC)
|
|| card->type == SDIO_TYPE_SDHC)
|
||||||
&& app_command(card, ACMD23, count))
|
&& app_command(card, ACMD23, count))
|
||||||
|
@ -411,16 +420,19 @@ sdio_error_t sdio_write_sectors(sdio_card_t *card, uint32_t sector, uint8_t *src
|
||||||
return set_error(card, SDIO_ERR_IO);
|
return set_error(card, SDIO_ERR_IO);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command(card, CMD25, sector))
|
if (command(card, multi ? CMD25 : CMD24, sector))
|
||||||
return set_error(card, SDIO_ERR_IO);
|
return set_error(card, SDIO_ERR_IO);
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
if (write_data_block(card, TOKEN_MULTI_TRAN, src) != SDIO_ERR_NONE)
|
if (write_data_block(card, multi ? TOKEN_MULTI_TRAN : TOKEN_SINGLE_TRAN, src) != SDIO_ERR_NONE){
|
||||||
return card->error;
|
return card->error;
|
||||||
|
}
|
||||||
src += SDIO_BLOCK_SIZE;
|
src += SDIO_BLOCK_SIZE;
|
||||||
}
|
}
|
||||||
spi_transfer_8(BUS, TOKEN_STOP_TRAN);
|
|
||||||
|
if (multi && command(card, CMD12, 0))
|
||||||
|
return set_error(card, SDIO_ERR_IO);
|
||||||
|
|
||||||
return set_error(card, SDIO_ERR_NONE);
|
return set_error(card, SDIO_ERR_NONE);
|
||||||
}
|
}
|
||||||
|
@ -449,4 +461,3 @@ sdio_error_t sdio_erase_sectors(sdio_card_t *card, uint32_t first, uint32_t last
|
||||||
|
|
||||||
return set_error(card, wait() ? SDIO_ERR_NONE : SDIO_ERR_TIMEOUT);
|
return set_error(card, wait() ? SDIO_ERR_NONE : SDIO_ERR_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,11 +7,13 @@ INC_DIRS += $(ssd1306_ROOT)..
|
||||||
SSD1306_I2C_SUPPORT ?= 1
|
SSD1306_I2C_SUPPORT ?= 1
|
||||||
# SPI4 support is on by default
|
# SPI4 support is on by default
|
||||||
SSD1306_SPI4_SUPPORT ?= 1
|
SSD1306_SPI4_SUPPORT ?= 1
|
||||||
|
# SPI3 support is on by default
|
||||||
|
SSD1306_SPI3_SUPPORT ?= 1
|
||||||
|
|
||||||
# args for passing into compile rule generation
|
# args for passing into compile rule generation
|
||||||
ssd1306_SRC_DIR = $(ssd1306_ROOT)
|
ssd1306_SRC_DIR = $(ssd1306_ROOT)
|
||||||
|
|
||||||
ssd1306_CFLAGS = -DSSD1306_I2C_SUPPORT=${SSD1306_I2C_SUPPORT} -DSSD1306_SPI4_SUPPORT=${SSD1306_SPI4_SUPPORT} $(CFLAGS)
|
ssd1306_CFLAGS = -DSSD1306_I2C_SUPPORT=${SSD1306_I2C_SUPPORT} -DSSD1306_SPI4_SUPPORT=${SSD1306_SPI4_SUPPORT} -DSSD1306_SPI3_SUPPORT=${SSD1306_SPI3_SUPPORT} $(CFLAGS)
|
||||||
|
|
||||||
|
|
||||||
$(eval $(call component_compile_rules,ssd1306))
|
$(eval $(call component_compile_rules,ssd1306))
|
||||||
|
|
|
@ -236,7 +236,9 @@ static int sh1106_go_coordinate(const ssd1306_t *dev, uint8_t x, uint8_t y)
|
||||||
int ssd1306_load_frame_buffer(const ssd1306_t *dev, uint8_t buf[])
|
int ssd1306_load_frame_buffer(const ssd1306_t *dev, uint8_t buf[])
|
||||||
{
|
{
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
|
#if (SSD1306_SPI3_SUPPORT)
|
||||||
uint8_t j;
|
uint8_t j;
|
||||||
|
#endif
|
||||||
#if (SSD1306_I2C_SUPPORT)
|
#if (SSD1306_I2C_SUPPORT)
|
||||||
uint8_t tab[16] = { 0 };
|
uint8_t tab[16] = { 0 };
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -40,30 +40,55 @@
|
||||||
|
|
||||||
#define UART0_RX_SIZE (128) // ESP8266 UART HW FIFO size
|
#define UART0_RX_SIZE (128) // ESP8266 UART HW FIFO size
|
||||||
|
|
||||||
static SemaphoreHandle_t uart0_sem = NULL;
|
static QueueHandle_t uart0_queue;
|
||||||
static bool inited = false;
|
static bool inited = false;
|
||||||
static void uart0_rx_init(void);
|
static bool uart0_rx_init(void);
|
||||||
|
static int uart0_nonblock;
|
||||||
|
static TickType_t uart0_vtime = portMAX_DELAY;
|
||||||
|
|
||||||
|
uint32_t uart0_parity_errors;
|
||||||
|
uint32_t uart0_framing_errors;
|
||||||
|
uint32_t uart0_breaks_detected;
|
||||||
|
|
||||||
IRAM void uart0_rx_handler(void *arg)
|
IRAM void uart0_rx_handler(void *arg)
|
||||||
{
|
{
|
||||||
// TODO: Handle UART1, see reg 0x3ff20020, bit2, bit0 represents uart1 and uart0 respectively
|
// TODO: Handle UART1, see reg 0x3ff20020, bit2, bit0 represents uart1 and uart0 respectively
|
||||||
if (!UART(UART0).INT_STATUS & UART_INT_STATUS_RXFIFO_FULL) {
|
|
||||||
return;
|
// printf(" [%08x (%d)]\n", READ_PERI_REG(UART_INT_ST(UART0)), READ_PERI_REG(UART_STATUS(UART0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S));
|
||||||
}
|
|
||||||
// printf(" [%08x (%d)]\n", READ_PERI_REG(UART_INT_ST(UART0)), READ_PERI_REG(UART_STATUS(UART0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S));
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
||||||
if (UART(UART0).INT_STATUS & UART_INT_STATUS_RXFIFO_FULL) {
|
|
||||||
UART(UART0).INT_CLEAR = UART_INT_CLEAR_RXFIFO_FULL;
|
do {
|
||||||
if (UART(UART0).STATUS & (UART_STATUS_RXFIFO_COUNT_M << UART_STATUS_RXFIFO_COUNT_S)) {
|
// If new data arrives and the status changes after checking here, them
|
||||||
long int xHigherPriorityTaskWoken;
|
// the interrupt will be re-triggered.
|
||||||
_xt_isr_mask(1 << INUM_UART);
|
uint32_t int_status = UART(UART0).INT_STATUS;
|
||||||
_xt_clear_ints(1<<INUM_UART);
|
|
||||||
xSemaphoreGiveFromISR(uart0_sem, &xHigherPriorityTaskWoken);
|
if (int_status & UART_INT_STATUS_RXFIFO_FULL) {
|
||||||
if(xHigherPriorityTaskWoken) {
|
size_t count = UART(UART0).STATUS & (UART_STATUS_RXFIFO_COUNT_M << UART_STATUS_RXFIFO_COUNT_S);
|
||||||
portYIELD();
|
for (size_t i = 0; i < count; i++) {
|
||||||
|
char ch = UART(UART0).FIFO & (UART_FIFO_DATA_M << UART_FIFO_DATA_S);
|
||||||
|
xQueueSendToBackFromISR(uart0_queue, &ch, &xHigherPriorityTaskWoken);
|
||||||
}
|
}
|
||||||
|
UART(UART0).INT_CLEAR = UART_INT_CLEAR_RXFIFO_FULL;
|
||||||
|
// If new data has arrived then the interrupt status will remain set.
|
||||||
|
} else if (int_status & UART_INT_STATUS_PARITY_ERR) {
|
||||||
|
uart0_parity_errors++;
|
||||||
|
UART(UART0).INT_CLEAR = UART_INT_CLEAR_PARITY_ERR;
|
||||||
|
} else if (int_status & UART_INT_STATUS_FRAMING_ERR) {
|
||||||
|
uart0_framing_errors++;
|
||||||
|
UART(UART0).INT_CLEAR = UART_INT_CLEAR_FRAMING_ERR;
|
||||||
|
} else if (int_status & UART_INT_STATUS_BREAK_DETECTED) {
|
||||||
|
uart0_breaks_detected++;
|
||||||
|
UART(UART0).INT_CLEAR = UART_INT_CLEAR_BREAK_DETECTED;
|
||||||
|
} else if (int_status & 0xff) {
|
||||||
|
printf("Error: unexpected uart irq, INT_STATUS 0x%02x\n", int_status);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} while (1);
|
||||||
printf("Error: unexpected uart irq, INT_STATUS 0x%02x\n", UART(UART0).INT_STATUS);
|
|
||||||
|
if(xHigherPriorityTaskWoken) {
|
||||||
|
portYIELD();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,31 +96,61 @@ uint32_t uart0_num_char(void)
|
||||||
{
|
{
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
if (!inited) uart0_rx_init();
|
if (!inited) uart0_rx_init();
|
||||||
count = UART(UART0).STATUS & (UART_STATUS_RXFIFO_COUNT_M << UART_STATUS_RXFIFO_COUNT_S);
|
count = uxQueueMessagesWaiting(uart0_queue);
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int uart0_set_nonblock(int nonblock)
|
||||||
|
{
|
||||||
|
int current = uart0_nonblock;
|
||||||
|
uart0_nonblock = nonblock;
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
TickType_t uart0_set_vtime(TickType_t ticks)
|
||||||
|
{
|
||||||
|
TickType_t current = uart0_vtime;
|
||||||
|
uart0_vtime = ticks;
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
// _read_stdin_r in core/newlib_syscalls.c will be skipped by the linker in favour
|
// _read_stdin_r in core/newlib_syscalls.c will be skipped by the linker in favour
|
||||||
// of this function
|
// of this function
|
||||||
long _read_stdin_r(struct _reent *r, int fd, char *ptr, int len)
|
long _read_stdin_r(struct _reent *r, int fd, char *ptr, int len)
|
||||||
{
|
{
|
||||||
|
TickType_t vtime = uart0_vtime;
|
||||||
|
int nonblock = uart0_nonblock;
|
||||||
|
|
||||||
|
if (nonblock) {
|
||||||
|
vtime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!inited) uart0_rx_init();
|
if (!inited) uart0_rx_init();
|
||||||
for(int i = 0; i < len; i++) {
|
|
||||||
if (!(UART(UART0).STATUS & (UART_STATUS_RXFIFO_COUNT_M << UART_STATUS_RXFIFO_COUNT_S))) {
|
for(size_t i = 0; i < len; i++, ptr++) {
|
||||||
_xt_isr_unmask(1 << INUM_UART);
|
if (xQueueReceive(uart0_queue, (void*)ptr, vtime) == pdFALSE) {
|
||||||
if (!xSemaphoreTake(uart0_sem, portMAX_DELAY)) {
|
if (i > 0) {
|
||||||
printf("\nFailed to get sem\n");
|
return i;
|
||||||
}
|
}
|
||||||
|
if (nonblock) {
|
||||||
|
r->_errno = EAGAIN;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
ptr[i] = UART(UART0).FIFO & (UART_FIFO_DATA_M << UART_FIFO_DATA_S);
|
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uart0_rx_init(void)
|
static bool uart0_rx_init(void)
|
||||||
{
|
{
|
||||||
|
uart0_queue = xQueueCreate(64, sizeof(char));
|
||||||
|
|
||||||
|
if (!uart0_queue) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int trig_lvl = 1;
|
int trig_lvl = 1;
|
||||||
uart0_sem = xSemaphoreCreateCounting(UART0_RX_SIZE, 0);
|
|
||||||
|
|
||||||
_xt_isr_attach(INUM_UART, uart0_rx_handler, NULL);
|
_xt_isr_attach(INUM_UART, uart0_rx_handler, NULL);
|
||||||
_xt_isr_unmask(1 << INUM_UART);
|
_xt_isr_unmask(1 << INUM_UART);
|
||||||
|
@ -112,7 +167,10 @@ static void uart0_rx_init(void)
|
||||||
UART(UART0).INT_CLEAR = 0x1ff;
|
UART(UART0).INT_CLEAR = 0x1ff;
|
||||||
|
|
||||||
// enable rx_interrupt
|
// enable rx_interrupt
|
||||||
UART(UART0).INT_ENABLE = UART_INT_ENABLE_RXFIFO_FULL;
|
UART(UART0).INT_ENABLE = UART_INT_ENABLE_RXFIFO_FULL | UART_INT_ENABLE_PARITY_ERR |
|
||||||
|
UART_INT_ENABLE_FRAMING_ERR | UART_INT_ENABLE_BREAK_DETECTED;
|
||||||
|
|
||||||
inited = true;
|
inited = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,16 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
// Return number of characters waiting in UART0
|
/* Return number of characters waiting in UART0. */
|
||||||
uint32_t uart0_num_char(void);
|
uint32_t uart0_num_char(void);
|
||||||
|
|
||||||
|
/* Set UART0 input to nonblocking or blocking, returning the old state. */
|
||||||
|
int uart0_set_nonblock(int);
|
||||||
|
|
||||||
|
/* Set the UART0 input wait time in ticks, or zero to wait indefinitely,
|
||||||
|
* returning the old wait time. The wait time is only used when the input is
|
||||||
|
* blocking.
|
||||||
|
*/
|
||||||
|
TickType_t uart0_set_vtime(TickType_t ticks);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1375,6 +1375,45 @@ void wificfg_got_sta_connect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void wificfg_wait_until_sta_connected()
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
uint8_t connect_status = sdk_wifi_station_get_connect_status();
|
||||||
|
if (connect_status == STATION_GOT_IP)
|
||||||
|
break;
|
||||||
|
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Notifty wificfg to disable the AP interface on the next restart
|
||||||
|
* if that option is enabled.
|
||||||
|
*/
|
||||||
|
wificfg_got_sta_connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct shutdown_hook {
|
||||||
|
struct shutdown_hook *next;
|
||||||
|
void (*fn)(void *);
|
||||||
|
void *arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct shutdown_hook *shutdown_hooks;
|
||||||
|
|
||||||
|
bool wificfg_add_shutdown_hook(void (*fn)(void *), void *arg)
|
||||||
|
{
|
||||||
|
struct shutdown_hook *hook = malloc(sizeof(struct shutdown_hook));
|
||||||
|
|
||||||
|
if (!hook) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hook->next = shutdown_hooks;
|
||||||
|
hook->fn = fn;
|
||||||
|
hook->arg = arg;
|
||||||
|
shutdown_hooks = hook;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static int handle_restart_post(int s, wificfg_method method,
|
static int handle_restart_post(int s, wificfg_method method,
|
||||||
uint32_t content_length,
|
uint32_t content_length,
|
||||||
wificfg_content_type content_type,
|
wificfg_content_type content_type,
|
||||||
|
@ -1382,6 +1421,10 @@ static int handle_restart_post(int s, wificfg_method method,
|
||||||
{
|
{
|
||||||
wificfg_write_string(s, http_redirect_header);
|
wificfg_write_string(s, http_redirect_header);
|
||||||
close(s);
|
close(s);
|
||||||
|
struct shutdown_hook *hook;
|
||||||
|
for (hook = shutdown_hooks; hook; hook = hook->next) {
|
||||||
|
hook->fn(hook->arg);
|
||||||
|
}
|
||||||
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
vTaskDelay(2000 / portTICK_PERIOD_MS);
|
||||||
sdk_system_restart();
|
sdk_system_restart();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1841,8 +1884,11 @@ static void server_task(void *pvParameters)
|
||||||
value = skip_whitespace(value);
|
value = skip_whitespace(value);
|
||||||
switch (header) {
|
switch (header) {
|
||||||
case HTTP_HEADER_HOST:
|
case HTTP_HEADER_HOST:
|
||||||
if (hostname_local && host_is_name(value) &&
|
if (!host_is_name(value)) {
|
||||||
strcmp(value, hostname_local)) {
|
break;
|
||||||
|
}
|
||||||
|
if (!hostname_local ||
|
||||||
|
(hostname_local && strcmp(value, hostname_local))) {
|
||||||
host_redirect = true;
|
host_redirect = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2006,6 +2052,21 @@ void wificfg_init(uint32_t port, const wificfg_dispatch *dispatch)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Default a hostname. */
|
||||||
|
char *hostname = NULL;
|
||||||
|
sysparam_get_string("hostname", &hostname);
|
||||||
|
if (!hostname && wificfg_default_hostname) {
|
||||||
|
uint8_t macaddr[6];
|
||||||
|
char name[32];
|
||||||
|
sdk_wifi_get_macaddr(1, macaddr);
|
||||||
|
snprintf(name, sizeof(name), wificfg_default_hostname, macaddr[3],
|
||||||
|
macaddr[4], macaddr[5]);
|
||||||
|
sysparam_set_string("hostname", name);
|
||||||
|
}
|
||||||
|
if (hostname) {
|
||||||
|
free(hostname);
|
||||||
|
}
|
||||||
|
|
||||||
sysparam_get_string("wifi_ap_ssid", &wifi_ap_ssid);
|
sysparam_get_string("wifi_ap_ssid", &wifi_ap_ssid);
|
||||||
sysparam_get_string("wifi_ap_password", &wifi_ap_password);
|
sysparam_get_string("wifi_ap_password", &wifi_ap_password);
|
||||||
sysparam_get_string("wifi_sta_ssid", &wifi_sta_ssid);
|
sysparam_get_string("wifi_sta_ssid", &wifi_sta_ssid);
|
||||||
|
@ -2077,21 +2138,6 @@ void wificfg_init(uint32_t port, const wificfg_dispatch *dispatch)
|
||||||
sdk_wifi_set_opmode(wifi_mode);
|
sdk_wifi_set_opmode(wifi_mode);
|
||||||
|
|
||||||
if (wifi_sta_enable) {
|
if (wifi_sta_enable) {
|
||||||
/* Default a hostname. */
|
|
||||||
char *hostname = NULL;
|
|
||||||
sysparam_get_string("hostname", &hostname);
|
|
||||||
if (!hostname && wificfg_default_hostname) {
|
|
||||||
uint8_t macaddr[6];
|
|
||||||
char name[32];
|
|
||||||
sdk_wifi_get_macaddr(1, macaddr);
|
|
||||||
snprintf(name, sizeof(name), wificfg_default_hostname, macaddr[3],
|
|
||||||
macaddr[4], macaddr[5]);
|
|
||||||
sysparam_set_string("hostname", name);
|
|
||||||
}
|
|
||||||
if (hostname) {
|
|
||||||
free(hostname);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sdk_station_config config;
|
struct sdk_station_config config;
|
||||||
strcpy((char *)config.ssid, wifi_sta_ssid);
|
strcpy((char *)config.ssid, wifi_sta_ssid);
|
||||||
strcpy((char *)config.password, wifi_sta_password);
|
strcpy((char *)config.password, wifi_sta_password);
|
||||||
|
|
|
@ -121,11 +121,11 @@ ssize_t wificfg_write_chunk_end(int s);
|
||||||
/* Write a html title meta data, using the hostname or AP SSI. */
|
/* Write a html title meta data, using the hostname or AP SSI. */
|
||||||
int wificfg_write_html_title(int s, char *buf, size_t len, const char *str);
|
int wificfg_write_html_title(int s, char *buf, size_t len, const char *str);
|
||||||
|
|
||||||
/* Callback to notify the wificfg logic that a station connection has been
|
/* Wait until the station interface has connected to an access point,
|
||||||
* successfully established. It might use this to disable the AP interface after
|
* and obtained an IP address. */
|
||||||
* a restart.
|
void wificfg_wait_until_sta_connected(void);
|
||||||
*/
|
|
||||||
void wificfg_got_sta_connect(void);
|
bool wificfg_add_shutdown_hook(void (*fn)(void *), void *arg);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ static inline void init_descriptors_list(uint8_t *buf, uint32_t total_dma_data_s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ws2812_i2s_init(uint32_t pixels_number, pixeltype_t type)
|
int ws2812_i2s_init(uint32_t pixels_number, pixeltype_t type)
|
||||||
{
|
{
|
||||||
dma_buffer_size = pixels_number * type;
|
dma_buffer_size = pixels_number * type;
|
||||||
dma_block_list_size = dma_buffer_size / MAX_DMA_BLOCK_SIZE;
|
dma_block_list_size = dma_buffer_size / MAX_DMA_BLOCK_SIZE;
|
||||||
|
@ -130,11 +130,24 @@ void ws2812_i2s_init(uint32_t pixels_number, pixeltype_t type)
|
||||||
|
|
||||||
debug("allocating %d dma blocks\n", dma_block_list_size);
|
debug("allocating %d dma blocks\n", dma_block_list_size);
|
||||||
|
|
||||||
dma_block_list = (dma_descriptor_t*)malloc(
|
if(!dma_block_list)
|
||||||
dma_block_list_size * sizeof(dma_descriptor_t));
|
{
|
||||||
|
dma_block_list = (dma_descriptor_t*)malloc(
|
||||||
|
dma_block_list_size * sizeof(dma_descriptor_t));
|
||||||
|
if(!dma_block_list)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
debug("allocating %d bytes for DMA buffer\n", dma_buffer_size);
|
debug("allocating %d bytes for DMA buffer\n", dma_buffer_size);
|
||||||
dma_buffer = malloc(dma_buffer_size);
|
if(!dma_buffer)
|
||||||
|
{
|
||||||
|
dma_buffer = malloc(dma_buffer_size);
|
||||||
|
if(!dma_buffer)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
memset(dma_buffer, 0xFA, dma_buffer_size);
|
memset(dma_buffer, 0xFA, dma_buffer_size);
|
||||||
|
|
||||||
init_descriptors_list(dma_buffer, dma_buffer_size);
|
init_descriptors_list(dma_buffer, dma_buffer_size);
|
||||||
|
@ -146,6 +159,7 @@ void ws2812_i2s_init(uint32_t pixels_number, pixeltype_t type)
|
||||||
clock_div.bclk_div, clock_div.clkm_div);
|
clock_div.bclk_div, clock_div.clkm_div);
|
||||||
|
|
||||||
i2s_dma_init(dma_isr_handler, NULL, clock_div, i2s_pins);
|
i2s_dma_init(dma_isr_handler, NULL, clock_div, i2s_pins);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const IRAM_DATA int16_t bitpatterns[16] =
|
const IRAM_DATA int16_t bitpatterns[16] =
|
||||||
|
|
|
@ -53,7 +53,7 @@ typedef enum {
|
||||||
*
|
*
|
||||||
* @param pixels_number Number of pixels in the strip.
|
* @param pixels_number Number of pixels in the strip.
|
||||||
*/
|
*/
|
||||||
void ws2812_i2s_init(uint32_t pixels_number, pixeltype_t type);
|
int ws2812_i2s_init(uint32_t pixels_number, pixeltype_t type);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update ws2812 pixels.
|
* Update ws2812 pixels.
|
||||||
|
|
|
@ -113,7 +113,11 @@ SECTIONS
|
||||||
*libc.a:*bzero.o(.literal .text .literal.* .text.*)
|
*libc.a:*bzero.o(.literal .text .literal.* .text.*)
|
||||||
*libc.a:*lock.o(.literal .text .literal.* .text.*)
|
*libc.a:*lock.o(.literal .text .literal.* .text.*)
|
||||||
|
|
||||||
*libc.a:*printf.o(.literal .text .literal.* .text.*)
|
*libc.a:*-printf.o(.literal .text .literal.* .text.*)
|
||||||
|
*libc.a:*-sprintf.o(.literal .text .literal.* .text.*)
|
||||||
|
*libc.a:*-fprintf.o(.literal .text .literal.* .text.*)
|
||||||
|
*libc.a:*-svfprintf.o(.literal .text .literal.* .text.*)
|
||||||
|
*libc.a:*-vfprintf.o(.literal .text .literal.* .text.*)
|
||||||
*libc.a:*findfp.o(.literal .text .literal.* .text.*)
|
*libc.a:*findfp.o(.literal .text .literal.* .text.*)
|
||||||
*libc.a:*fputwc.o(.literal .text .literal.* .text.*)
|
*libc.a:*fputwc.o(.literal .text .literal.* .text.*)
|
||||||
|
|
||||||
|
@ -249,10 +253,13 @@ SECTIONS
|
||||||
*(.gnu.linkonce.r.*)
|
*(.gnu.linkonce.r.*)
|
||||||
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
||||||
*(.xt_except_table)
|
*(.xt_except_table)
|
||||||
*(.gcc_except_table)
|
*(.gcc_except_table .gcc_except_table.*)
|
||||||
*(.gnu.linkonce.e.*)
|
*(.gnu.linkonce.e.*)
|
||||||
*(.gnu.version_r)
|
*(.gnu.version_r)
|
||||||
*(.eh_frame)
|
. = (. + 3) & ~ 3;
|
||||||
|
__eh_frame = ABSOLUTE(.);
|
||||||
|
KEEP(*(.eh_frame))
|
||||||
|
. = (. + 7) & ~ 3;
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
*(.dynamic)
|
*(.dynamic)
|
||||||
*(.gnu.version_d)
|
*(.gnu.version_d)
|
||||||
|
|
22
ld/rom.ld
22
ld/rom.ld
|
@ -57,18 +57,18 @@ PROVIDE ( __umoddi3 = 0x4000d770 );
|
||||||
PROVIDE ( __umodsi3 = 0x4000e268 );
|
PROVIDE ( __umodsi3 = 0x4000e268 );
|
||||||
PROVIDE ( __umulsidi3 = 0x4000dcf0 );
|
PROVIDE ( __umulsidi3 = 0x4000dcf0 );
|
||||||
|
|
||||||
PROVIDE ( bzero = 0x40002ae8 );
|
PROVIDE ( bzero = 0x4000de84 );
|
||||||
PROVIDE ( memcmp = 0x400018d4 );
|
PROVIDE ( memcmp = 0x4000dea8 );
|
||||||
PROVIDE ( memcpy = 0x400018b4 );
|
PROVIDE ( memcpy = 0x4000df48 );
|
||||||
PROVIDE ( memmove = 0x400018c4 );
|
PROVIDE ( memmove = 0x4000e04c );
|
||||||
PROVIDE ( memset = 0x400018a4 );
|
PROVIDE ( memset = 0x4000e190 );
|
||||||
|
|
||||||
PROVIDE ( strcmp = 0x40002aa8 );
|
PROVIDE ( strcmp = 0x4000bdc8 );
|
||||||
PROVIDE ( strcpy = 0x40002a88 );
|
PROVIDE ( strcpy = 0x4000bec8 );
|
||||||
PROVIDE ( strlen = 0x40002ac8 );
|
PROVIDE ( strlen = 0x4000bf4c );
|
||||||
PROVIDE ( strncmp = 0x40002ab8 );
|
PROVIDE ( strncmp = 0x4000bfa8 );
|
||||||
PROVIDE ( strncpy = 0x40002a98 );
|
PROVIDE ( strncpy = 0x4000c0a0 );
|
||||||
PROVIDE ( strstr = 0x40002ad8 );
|
PROVIDE ( strstr = 0x4000e1e0 );
|
||||||
|
|
||||||
PROVIDE ( ETS_INTR_LOCK = 0x40000f74 );
|
PROVIDE ( ETS_INTR_LOCK = 0x40000f74 );
|
||||||
PROVIDE ( ETS_INTR_UNLOCK = 0x40000f80 );
|
PROVIDE ( ETS_INTR_UNLOCK = 0x40000f80 );
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
Newlib from git://sourceware.org/git/newlib-cygwin.git with xtensa & locking patches see https://github.com/ourairquality/newlib and built from commit 7558d27f9dba58ba0e51e37a2aa3ea6be7214799
|
Newlib from git://sourceware.org/git/newlib-cygwin.git with xtensa & locking patches see https://github.com/ourairquality/newlib and built from commit 984b749fb223daab954060c04720933290584f00
|
||||||
|
|
||||||
The build commands were:
|
The build commands were:
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
../configure --with-newlib --enable-multilib --disable-newlib-io-c99-formats --enable-newlib-supplied-syscalls --enable-target-optspace --program-transform-name="s&^&xtensa-lx106-elf-&" --disable-option-checking --with-target-subdir=xtensa-lx106-elf --target=xtensa-lx106-elf --enable-newlib-nano-malloc --enable-newlib-nano-formatted-io --enable-newlib-reent-small --disable-newlib-mb --prefix=/tmp/libc
|
../configure --with-newlib --enable-multilib --disable-newlib-io-c99-formats --enable-newlib-supplied-syscalls --enable-target-optspace --program-transform-name="s&^&xtensa-lx106-elf-&" --disable-option-checking --with-target-subdir=xtensa-lx106-elf --target=xtensa-lx106-elf --enable-newlib-nano-malloc --enable-newlib-nano-formatted-io --enable-newlib-reent-small --disable-newlib-mb --enable-newlib-global-stdio-streams --prefix=/tmp/libc
|
||||||
env CROSS_CFLAGS="-DSIGNAL_PROVIDED -DABORT_PROVIDED" make
|
env CROSS_CFLAGS="-DSIGNAL_PROVIDED -DABORT_PROVIDED" make
|
||||||
make install
|
make install
|
||||||
|
|
|
@ -133,6 +133,10 @@ extern int malloc_trim (size_t);
|
||||||
extern int _malloc_trim_r (struct _reent *, size_t);
|
extern int _malloc_trim_r (struct _reent *, size_t);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
extern void __malloc_lock(struct _reent *);
|
||||||
|
|
||||||
|
extern void __malloc_unlock(struct _reent *);
|
||||||
|
|
||||||
/* A compatibility routine for an earlier version of the allocator. */
|
/* A compatibility routine for an earlier version of the allocator. */
|
||||||
|
|
||||||
extern void mstats (char *);
|
extern void mstats (char *);
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
/* Define to move the stdio stream FILE objects out of struct _reent and make
|
/* Define to move the stdio stream FILE objects out of struct _reent and make
|
||||||
them global. The stdio stream pointers of struct _reent are initialized to
|
them global. The stdio stream pointers of struct _reent are initialized to
|
||||||
point to the global stdio FILE stream objects. */
|
point to the global stdio FILE stream objects. */
|
||||||
/* #undef _WANT_REENT_GLOBAL_STDIO_STREAMS */
|
#define _WANT_REENT_GLOBAL_STDIO_STREAMS 1
|
||||||
|
|
||||||
/* Define if small footprint nano-formatted-IO implementation used. */
|
/* Define if small footprint nano-formatted-IO implementation used. */
|
||||||
#define _NANO_FORMATTED_IO 1
|
#define _NANO_FORMATTED_IO 1
|
||||||
|
|
|
@ -144,7 +144,7 @@ struct __sbuf {
|
||||||
* _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
|
* _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef _REENT_SMALL
|
#if defined(_REENT_SMALL) && !defined(_REENT_GLOBAL_STDIO_STREAMS)
|
||||||
/*
|
/*
|
||||||
* struct __sFILE_fake is the start of a struct __sFILE, with only the
|
* struct __sFILE_fake is the start of a struct __sFILE, with only the
|
||||||
* minimal fields allocated. In __sinit() we really allocate the 3
|
* minimal fields allocated. In __sinit() we really allocate the 3
|
||||||
|
@ -418,6 +418,43 @@ struct _reent
|
||||||
char *_signal_buf; /* strsignal */
|
char *_signal_buf; /* strsignal */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef _REENT_GLOBAL_STDIO_STREAMS
|
||||||
|
extern __FILE __sf[3];
|
||||||
|
|
||||||
|
# define _REENT_INIT(var) \
|
||||||
|
{ 0, \
|
||||||
|
&__sf[0], \
|
||||||
|
&__sf[1], \
|
||||||
|
&__sf[2], \
|
||||||
|
0, \
|
||||||
|
_NULL, \
|
||||||
|
0, \
|
||||||
|
0, \
|
||||||
|
_NULL, \
|
||||||
|
_NULL, \
|
||||||
|
_NULL, \
|
||||||
|
0, \
|
||||||
|
0, \
|
||||||
|
_NULL, \
|
||||||
|
_NULL, \
|
||||||
|
_NULL, \
|
||||||
|
_NULL, \
|
||||||
|
_NULL, \
|
||||||
|
_REENT_INIT_ATEXIT \
|
||||||
|
{_NULL, 0, _NULL}, \
|
||||||
|
_NULL, \
|
||||||
|
_NULL, \
|
||||||
|
_NULL \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _REENT_INIT_PTR_ZEROED(var) \
|
||||||
|
{ (var)->_stdin = &__sf[0]; \
|
||||||
|
(var)->_stdout = &__sf[1]; \
|
||||||
|
(var)->_stderr = &__sf[2]; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
extern const struct __sFILE_fake __sf_fake_stdin;
|
extern const struct __sFILE_fake __sf_fake_stdin;
|
||||||
extern const struct __sFILE_fake __sf_fake_stdout;
|
extern const struct __sFILE_fake __sf_fake_stdout;
|
||||||
extern const struct __sFILE_fake __sf_fake_stderr;
|
extern const struct __sFILE_fake __sf_fake_stderr;
|
||||||
|
@ -454,6 +491,8 @@ extern const struct __sFILE_fake __sf_fake_stderr;
|
||||||
(var)->_stderr = (__FILE *)&__sf_fake_stderr; \
|
(var)->_stderr = (__FILE *)&__sf_fake_stderr; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Only add assert() calls if we are specified to debug. */
|
/* Only add assert() calls if we are specified to debug. */
|
||||||
#ifdef _REENT_CHECK_DEBUG
|
#ifdef _REENT_CHECK_DEBUG
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -244,9 +244,9 @@ void sdk_ets_timer_disarm(ets_timer_t *timer)
|
||||||
prev = curr;
|
prev = curr;
|
||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
}
|
}
|
||||||
vPortExitCritical();
|
|
||||||
timer->next = ETS_TIMER_NOT_ARMED;
|
timer->next = ETS_TIMER_NOT_ARMED;
|
||||||
timer->period_ticks = 0;
|
timer->period_ticks = 0;
|
||||||
|
vPortExitCritical();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "esp/gpio_regs.h"
|
#include "esp/gpio_regs.h"
|
||||||
#include "esp/rtc_regs.h"
|
#include "esp/rtc_regs.h"
|
||||||
#include "sdk_internal.h"
|
#include "sdk_internal.h"
|
||||||
#include "xtensa/hal.h"
|
#include "xtensa_ops.h"
|
||||||
|
|
||||||
static int cpu_freq = 80;
|
static int cpu_freq = 80;
|
||||||
|
|
||||||
|
@ -28,9 +28,14 @@ void sdk_os_update_cpu_frequency(int freq) {
|
||||||
void sdk_ets_update_cpu_frequency(int freq) __attribute__ (( alias ("sdk_os_update_cpu_frequency") ));
|
void sdk_ets_update_cpu_frequency(int freq) __attribute__ (( alias ("sdk_os_update_cpu_frequency") ));
|
||||||
|
|
||||||
void sdk_os_delay_us(uint16_t us) {
|
void sdk_os_delay_us(uint16_t us) {
|
||||||
uint32_t start_ccount = xthal_get_ccount();
|
uint32_t start_ccount, ccount;
|
||||||
uint32_t delay_ccount = cpu_freq * us;
|
uint32_t delay_ccount = cpu_freq * us;
|
||||||
while (xthal_get_ccount() - start_ccount < delay_ccount) {}
|
|
||||||
|
RSR(start_ccount, ccount);
|
||||||
|
|
||||||
|
do {
|
||||||
|
RSR(ccount, ccount);
|
||||||
|
} while (ccount - start_ccount < delay_ccount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sdk_ets_delay_us(uint16_t us) __attribute__ (( alias ("sdk_os_delay_us") ));
|
void sdk_ets_delay_us(uint16_t us) __attribute__ (( alias ("sdk_os_delay_us") ));
|
||||||
|
|
|
@ -563,12 +563,12 @@ bool sdk_wifi_station_dhcpc_stop(void) {
|
||||||
if (sdk_wifi_get_opmode() == 2) {
|
if (sdk_wifi_get_opmode() == 2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
LOCK_TCPIP_CORE();
|
||||||
if (netif && sdk_dhcpc_flag == DHCP_STARTED) {
|
if (netif && sdk_dhcpc_flag == DHCP_STARTED) {
|
||||||
LOCK_TCPIP_CORE();
|
|
||||||
dhcp_stop(netif);
|
dhcp_stop(netif);
|
||||||
sdk_dhcpc_flag = DHCP_STOPPED;
|
|
||||||
UNLOCK_TCPIP_CORE();
|
|
||||||
}
|
}
|
||||||
|
sdk_dhcpc_flag = DHCP_STOPPED;
|
||||||
|
UNLOCK_TCPIP_CORE();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue