/* * See the serial2.h header file. */ xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) { xComPortHandle xReturn; UART_InitTypeDef UART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; EIC_IRQInitTypeDef EIC_IRQInitStructure; /* Create the queues used to hold Rx and Tx characters. */ xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); /* If the queues were created correctly then setup the serial port hardware. */ if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) ) { portENTER_CRITICAL(); { /* Enable the UART0 Clock. */ MRCC_PeripheralClockConfig( MRCC_Peripheral_UART0, ENABLE ); /* Configure the UART0_Tx as alternate function */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_Init(GPIO0, &GPIO_InitStructure); /* Configure the UART0_Rx as input floating */ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_Init(GPIO0, &GPIO_InitStructure); /* Configure UART0. */ UART_InitStructure.UART_WordLength = UART_WordLength_8D; UART_InitStructure.UART_StopBits = UART_StopBits_1; UART_InitStructure.UART_Parity = UART_Parity_No; UART_InitStructure.UART_BaudRate = ulWantedBaud; UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None; UART_InitStructure.UART_Mode = UART_Mode_Tx_Rx; UART_InitStructure.UART_TxFIFOLevel = UART_FIFOLevel_1_2; /* FIFO size 16 bytes, FIFO level 8 bytes */ UART_InitStructure.UART_RxFIFOLevel = UART_FIFOLevel_1_2; /* FIFO size 16 bytes, FIFO level 8 bytes */ UART_Init(UART0, &UART_InitStructure); /* Enable the UART0 */ UART_Cmd(UART0, ENABLE); /* Configure the IEC for the UART interrupts. */ EIC_IRQInitStructure.EIC_IRQChannelCmd = ENABLE; EIC_IRQInitStructure.EIC_IRQChannel = UART0_IRQChannel; EIC_IRQInitStructure.EIC_IRQChannelPriority = 1; EIC_IRQInit(&EIC_IRQInitStructure); xQueueEmpty = pdTRUE; UART_ITConfig( UART0, UART_IT_Transmit | UART_IT_Receive, ENABLE ); } portEXIT_CRITICAL(); } else { xReturn = ( xComPortHandle ) 0; } /* This demo file only supports a single port but we have to return something to comply with the standard demo header file. */ return xReturn; }
void adc_init(adc_t* adc) { static int already_initialized = 0; gpio_clock_init(adc->GPIOx); GPIO_InitTypeDef GPIO_InitStructure = { .GPIO_Pin = adc->GPIO_Pin_x, .GPIO_Speed = GPIO_Speed_2MHz, .GPIO_Mode = GPIO_Mode_IN_FLOATING, }; GPIO_Init(adc->GPIOx, &GPIO_InitStructure); // avoid configuring ADC2 again: if (already_initialized) return; already_initialized = 1; adc_clock_init(ADC2); xADCMutex = xSemaphoreCreateMutex(); xADCQueue = xQueueCreate(10, sizeof(unsigned short)); ADC_Cmd(ADC2, ENABLE); // Wait until it stabilizes wait_us(1000); ADC_InitTypeDef ADC_InitStructure; ADC_StructInit(&ADC_InitStructure); ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC2, &ADC_InitStructure); ADC_StartCalibration(ADC2); while (ADC_GetCalibrationStatus(ADC2)); ADC_Cmd(ADC2, DISABLE); ADC_ITConfig(ADC2, ADC_IT_EOC, ENABLE); // Enable interrupt UART: NVIC_InitTypeDef NVIC_InitStructure = { .NVIC_IRQChannel = ADC1_2_IRQn, .NVIC_IRQChannelPreemptionPriority = 7, .NVIC_IRQChannelSubPriority = 0, .NVIC_IRQChannelCmd = ENABLE, }; NVIC_Init(&NVIC_InitStructure); ADC_Cmd(ADC2, ENABLE); } void ADC1_2_IRQHandler(void) { signed portBASE_TYPE xHigherPriorityTaskWoken; unsigned short in_buffer = ADC2->DR & 0xfff; xQueueSendToBackFromISR(xADCQueue, &in_buffer, &xHigherPriorityTaskWoken); portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } unsigned short adc_read(adc_t* adc) { unsigned short in_buffer; xSemaphoreTake(xADCMutex, portMAX_DELAY); // we use the same ADC for all peripherals ADC_RegularChannelConfig(ADC2, adc->ADC_Channel, 1, ADC_SampleTime_239Cycles5); ADC_Cmd(ADC2, ENABLE); xQueueReceive(xADCQueue, &in_buffer, portMAX_DELAY); xSemaphoreGive(xADCMutex); return in_buffer; }
void vStartAltBlockingQueueTasks( unsigned portBASE_TYPE uxPriority ) { xBlockingQueueParameters *pxQueueParameters1, *pxQueueParameters2; xBlockingQueueParameters *pxQueueParameters3, *pxQueueParameters4; xBlockingQueueParameters *pxQueueParameters5, *pxQueueParameters6; const unsigned portBASE_TYPE uxQueueSize1 = 1, uxQueueSize5 = 5; const portTickType xBlockTime = ( portTickType ) 1000 / portTICK_RATE_MS; const portTickType xDontBlock = ( portTickType ) 0; /* Create the first two tasks as described at the top of the file. */ /* First create the structure used to pass parameters to the consumer tasks. */ pxQueueParameters1 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); /* Create the queue used by the first two tasks to pass the incrementing number. Pass a pointer to the queue in the parameter structure. */ pxQueueParameters1->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); /* The consumer is created first so gets a block time as described above. */ pxQueueParameters1->xBlockTime = xBlockTime; /* Pass in the variable that this task is going to increment so we can check it is still running. */ pxQueueParameters1->psCheckVariable = &( sBlockingConsumerCount[ 0 ] ); /* Create the structure used to pass parameters to the producer task. */ pxQueueParameters2 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); /* Pass the queue to this task also, using the parameter structure. */ pxQueueParameters2->xQueue = pxQueueParameters1->xQueue; /* The producer is not going to block - as soon as it posts the consumer will wake and remove the item so the producer should always have room to post. */ pxQueueParameters2->xBlockTime = xDontBlock; /* Pass in the variable that this task is going to increment so we can check it is still running. */ pxQueueParameters2->psCheckVariable = &( sBlockingProducerCount[ 0 ] ); /* Note the producer has a lower priority than the consumer when the tasks are spawned. */ xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QConsB1", blckqSTACK_SIZE, ( void * ) pxQueueParameters1, uxPriority, NULL ); xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QProdB2", blckqSTACK_SIZE, ( void * ) pxQueueParameters2, tskIDLE_PRIORITY, NULL ); /* Create the second two tasks as described at the top of the file. This uses the same mechanism but reverses the task priorities. */ pxQueueParameters3 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); pxQueueParameters3->xQueue = xQueueCreate( uxQueueSize1, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); pxQueueParameters3->xBlockTime = xDontBlock; pxQueueParameters3->psCheckVariable = &( sBlockingProducerCount[ 1 ] ); pxQueueParameters4 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); pxQueueParameters4->xQueue = pxQueueParameters3->xQueue; pxQueueParameters4->xBlockTime = xBlockTime; pxQueueParameters4->psCheckVariable = &( sBlockingConsumerCount[ 1 ] ); xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QProdB3", blckqSTACK_SIZE, ( void * ) pxQueueParameters3, tskIDLE_PRIORITY, NULL ); xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QConsB4", blckqSTACK_SIZE, ( void * ) pxQueueParameters4, uxPriority, NULL ); /* Create the last two tasks as described above. The mechanism is again just the same. This time both parameter structures are given a block time. */ pxQueueParameters5 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); pxQueueParameters5->xQueue = xQueueCreate( uxQueueSize5, ( unsigned portBASE_TYPE ) sizeof( unsigned portSHORT ) ); pxQueueParameters5->xBlockTime = xBlockTime; pxQueueParameters5->psCheckVariable = &( sBlockingProducerCount[ 2 ] ); pxQueueParameters6 = ( xBlockingQueueParameters * ) pvPortMalloc( sizeof( xBlockingQueueParameters ) ); pxQueueParameters6->xQueue = pxQueueParameters5->xQueue; pxQueueParameters6->xBlockTime = xBlockTime; pxQueueParameters6->psCheckVariable = &( sBlockingConsumerCount[ 2 ] ); xTaskCreate( vBlockingQueueProducer, ( signed portCHAR * ) "QProdB5", blckqSTACK_SIZE, ( void * ) pxQueueParameters5, tskIDLE_PRIORITY, NULL ); xTaskCreate( vBlockingQueueConsumer, ( signed portCHAR * ) "QConsB6", blckqSTACK_SIZE, ( void * ) pxQueueParameters6, tskIDLE_PRIORITY, NULL ); }
/*---------------------------------------------------------------------------/ / Communication port init & open & close /---------------------------------------------------------------------------*/ xCOM SerialOpen(xCOM USARTx, u32 BaudRate, portBASE_TYPE uxQueueLength) { GPIO_InitTypeDef GPIO_InitStruct; USART_InitTypeDef USART_InitStruct; NVIC_InitTypeDef NVIC_InitStruct; xCOM xResult = (xCOM)NULL; u8 portNo = USARTx == USART1 ? 0 : 1; // Create Queue if(USARTx == USART1) { if(xUSART1_RxQueue == serINVALID_QUEUE) xUSART1_RxQueue = xQueueCreate(uxQueueLength, (unsigned portBASE_TYPE)sizeof(signed portCHAR)); if(xUSART1_TxQueue == serINVALID_QUEUE) xUSART1_TxQueue = xQueueCreate(uxQueueLength, (unsigned portBASE_TYPE)sizeof(signed portCHAR)); if(xUSART1_RxQueue == serINVALID_QUEUE || xUSART1_TxQueue == serINVALID_QUEUE) return xResult; } else if(USARTx == USART6) { if(xUSART6_RxQueue == serINVALID_QUEUE) xUSART6_RxQueue = xQueueCreate(uxQueueLength, (unsigned portBASE_TYPE)sizeof(signed portCHAR)); if(xUSART6_TxQueue == serINVALID_QUEUE) xUSART6_TxQueue = xQueueCreate(uxQueueLength, (unsigned portBASE_TYPE)sizeof(signed portCHAR)); if(xUSART6_RxQueue == serINVALID_QUEUE || xUSART6_TxQueue == serINVALID_QUEUE) return xResult; } // queue init xQueueInit(USARTx); // Enable USARTx clock if(USARTx == USART1) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); } else if(USARTx == USART6) { RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE); GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_USART6); GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_USART6); } //Configure USART1 Rx (PA10) as input floating GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStruct.GPIO_Pin = (USARTx == USART1 ? (GPIO_Pin_9 | GPIO_Pin_10) : (GPIO_Pin_6 | GPIO_Pin_7)); GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); // USART staus USART_InitStruct.USART_BaudRate = BaudRate; USART_InitStruct.USART_WordLength = USART_WordLength_8b; USART_InitStruct.USART_StopBits = USART_StopBits_1; USART_InitStruct.USART_Parity = USART_Parity_No ; USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USARTx, &USART_InitStruct); // RX Interrupt USART_ITConfig( USARTx, USART_IT_RXNE, ENABLE ); // Interrupt handler NVIC_InitStruct.NVIC_IRQChannel = (USARTx == USART1 ? USART1_IRQn : USART6_IRQn); NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0; NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStruct ); // Set communication port USART_Cmd( USARTx, ENABLE ); // Flag gIsComState[portNo] = TRUE; // 초기화 시킨 포트 리턴 return xResult = USARTx; }
/** * Creates a new mailbox. * * @param size is the number of entries in the mailbox. * @return the handle of the created mailbox. */ sys_mbox_t sys_mbox_new(int size) { unsigned long datasize; xQueueHandle mbox; u32_t i; /* Fail if the mailbox size is too large. */ if(size > MBOX_MAX) { #if SYS_STATS STATS_INC(sys.mbox.err); #endif /* SYS_STATS */ return 0; } /* Find a mailbox that is not in use. */ for(i = 0; i < SYS_MBOX_MAX; i++) { if(mboxes[i].queue == 0) { break; } } if(i == SYS_MBOX_MAX) { #if SYS_STATS STATS_INC(sys.mbox.err); #endif /* SYS_STATS */ return 0; } /* Compute the size of the queue memory required by this mailbox. */ datasize = (sizeof(void *) * size) + portQUEUE_OVERHEAD_BYTES; /* Create a queue for this mailbox. */ #if RTOS_SAFERTOS if(xQueueCreate(mboxes[i].buffer, datasize, size, sizeof(void *), &mbox) != pdPASS) { #elif RTOS_FREERTOS mbox = xQueueCreate(size, sizeof(void *)); if(mbox == NULL) { #endif /* RTOS_SAFERTOS */ #if SYS_STATS STATS_INC(sys.mbox.err); #endif /* SYS_STATS */ return 0; } /* Update the mailbox statistics. */ #if SYS_STATS STATS_INC(sys.mbox.used); #if LWIP_STATS if(lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used) { lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used; } #endif #endif /* SYS_STATS */ /* Save the queue handle. */ mboxes[i].queue = mbox; /* Return this mailbox. */ return &(mboxes[i]); } /** * Sends a message to a mailbox. * * @param mbox is the mailbox * @param msg is the message to send */ void sys_mbox_post(sys_mbox_t mbox, void *msg) { /* Send this message to the queue. */ while(xQueueSend(mbox->queue, &msg, portMAX_DELAY) != pdPASS); } /** * Tries to send a message to a mailbox. * * @param mbox is the mailbox * @param msg is the message to send * @return ERR_OK if the message was sent and ERR_MEM if there was no space for * the message */ err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg) { /* Send this message to the queue. */ if(xQueueSend(mbox->queue, &msg, 0) == pdPASS) { return ERR_OK; } /* Update the mailbox statistics. */ #if SYS_STATS STATS_INC(sys.mbox.err); #endif /* SYS_STATS */ /* The message could not be sent. */ return ERR_MEM; } /** * Retrieve a message from a mailbox. * * @param mbox is the mailbox * @param msg is a pointer to the location to receive the message * @param timeout is the maximum number of milliseconds to wait for the message * @return the number of milliseconds that passed before the message was * received, or SYS_ARCH_TIMEOUT if the tmieout occurred */ u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) { portTickType starttime; void *dummyptr; /* If the actual message contents are not required, provide a local variable to recieve the message. */ if(msg == NULL) { msg = &dummyptr; } /* Get the starting time. */ starttime = xTaskGetTickCount(); /* See if there is a timeout. */ if(timeout != 0) { /* Receive a message from the queue. */ if(xQueueReceive(mbox->queue, msg, timeout / portTICK_RATE_MS) == pdPASS) { /* Return the amount of time it took for the message to be received. */ return (xTaskGetTickCount() - starttime) * portTICK_RATE_MS; } else { /* No message arrived in the allotted time. */ *msg = NULL; return SYS_ARCH_TIMEOUT; } } else { /* Try to receive a message until one arrives. */ while(xQueueReceive(mbox->queue, msg, portMAX_DELAY) != pdPASS); /* Return the amount of time it took for the message to be received. */ return (xTaskGetTickCount() - starttime) * portTICK_RATE_MS; } }
void rtos_init_dispatcher() { main_queue_handle = xQueueCreate(32, sizeof(struct rtos_event)); xTaskCreate(disp_task, (const signed char *) "disp_task", (V7_STACK_SIZE + 1024) / 4, NULL, tskIDLE_PRIORITY + 2, &disp_task_handle); }
/* * See header file for parameter descriptions. */ long lCOMPortInit( unsigned long ulPort, unsigned long ulWantedBaud ) { long lReturn = pdFAIL; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; if( ulPort < serNUM_COM_PORTS ) { /* The common (not port dependent) part of the initialisation. */ USART_InitStructure.USART_BaudRate = ulWantedBaud; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* Init the buffer structures with the buffer for the COM port being initialised, and perform any non-common initialisation necessary. This does not check to see if the COM port has already been initialised. */ if( ulPort == 0 ) { /* Create the queue of chars that are waiting to be sent to COM0. */ xCharsForTx[ 0 ] = xQueueCreate( serTX_QUEUE_LEN, sizeof( char ) ); /* Create the queue used to hold characters received from COM0. */ xRxedChars[ 0 ] = xQueueCreate( serRX_QUEUE_LEN, sizeof( char ) ); /* Enable COM0 clock - the ST libraries start numbering from UART1. */ RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE ); /* Configure USART1 Rx (PA10) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init( GPIOA, &GPIO_InitStructure ); /* Configure USART1 Tx (PA9) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init( GPIOA, &GPIO_InitStructure ); USART_Init( USART1, &USART_InitStructure ); USART_ITConfig( USART1, USART_IT_RXNE, ENABLE ); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel; NVIC_Init( &NVIC_InitStructure ); USART_DMACmd( USART1, ( USART_DMAReq_Tx | USART_DMAReq_Rx ), ENABLE ); USART_Cmd( USART1, ENABLE ); /* Everything is ok. */ lReturn = pdPASS; } else if( ulPort == 1 ) { /* Create the queue of chars that are waiting to be sent to COM1. */ xCharsForTx[ 1 ] = xQueueCreate( serTX_QUEUE_LEN, sizeof( char ) ); /* Create the queue used to hold characters received from COM0. */ xRxedChars[ 1 ] = xQueueCreate( serRX_QUEUE_LEN, sizeof( char ) ); /* Enable COM0 clock - the ST libraries start numbering from 1. */ RCC_APB2PeriphClockCmd( RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOA, ENABLE ); /* Configure USART2 Rx (PA3) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init( GPIOA, &GPIO_InitStructure ); /* Configure USART2 Tx (PA2) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init( GPIOA, &GPIO_InitStructure ); USART_Init( USART2, &USART_InitStructure ); USART_ITConfig( USART2, USART_IT_RXNE, ENABLE ); NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQChannel; NVIC_Init( &NVIC_InitStructure ); USART_DMACmd( USART2, ( USART_DMAReq_Tx | USART_DMAReq_Rx ), ENABLE ); USART_Cmd( USART2, ENABLE ); /* Everything is ok. */ lReturn = pdPASS; } else { /* Nothing to do unless more than two ports are supported. */ } } return lReturn; }
/* * See the serial2.h header file. */ xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength ) { xComPortHandle xReturn; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Create the queues used to hold Rx/Tx characters. */ xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed char ) ); /* If the queue/semaphore was created correctly then setup the serial port hardware. */ if( ( xRxedChars != serINVALID_QUEUE ) && ( xCharsForTx != serINVALID_QUEUE ) ) { /* Enable USART1 clock */ RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE ); /* Configure USART1 Rx (PA10) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init( GPIOA, &GPIO_InitStructure ); /* Configure USART1 Tx (PA9) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init( GPIOA, &GPIO_InitStructure ); USART_InitStructure.USART_BaudRate = ulWantedBaud; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No ; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStructure.USART_Clock = USART_Clock_Disable; USART_InitStructure.USART_CPOL = USART_CPOL_Low; USART_InitStructure.USART_CPHA = USART_CPHA_2Edge; USART_InitStructure.USART_LastBit = USART_LastBit_Disable; USART_Init( USART1, &USART_InitStructure ); USART_ITConfig( USART1, USART_IT_RXNE, ENABLE ); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_KERNEL_INTERRUPT_PRIORITY; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init( &NVIC_InitStructure ); USART_Cmd( USART1, ENABLE ); } else { xReturn = ( xComPortHandle ) 0; } /* This demo file only supports a single port but we have to return something to comply with the standard demo header file. */ return xReturn; }
esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *bus_config, const spi_slave_interface_config_t *slave_config, int dma_chan) { bool native, claimed; //We only support HSPI/VSPI, period. SPI_CHECK(VALID_HOST(host), "invalid host", ESP_ERR_INVALID_ARG); claimed = spicommon_periph_claim(host); SPI_CHECK(claimed, "host already in use", ESP_ERR_INVALID_STATE); spihost[host] = malloc(sizeof(spi_slave_t)); if (spihost[host] == NULL) goto nomem; memset(spihost[host], 0, sizeof(spi_slave_t)); memcpy(&spihost[host]->cfg, slave_config, sizeof(spi_slave_interface_config_t)); spicommon_bus_initialize_io(host, bus_config, dma_chan, SPICOMMON_BUSFLAG_SLAVE, &native); gpio_set_direction(slave_config->spics_io_num, GPIO_MODE_INPUT); spicommon_cs_initialize(host, slave_config->spics_io_num, 0, native == false); spihost[host]->no_gpio_matrix = native; spihost[host]->dma_chan = dma_chan; if (dma_chan != 0) { //See how many dma descriptors we need and allocate them int dma_desc_ct = (bus_config->max_transfer_sz + SPI_MAX_DMA_LEN - 1) / SPI_MAX_DMA_LEN; if (dma_desc_ct == 0) dma_desc_ct = 1; //default to 4k when max is not given spihost[host]->max_transfer_sz = dma_desc_ct * SPI_MAX_DMA_LEN; spihost[host]->dmadesc_tx = pvPortMallocCaps(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA); spihost[host]->dmadesc_rx = pvPortMallocCaps(sizeof(lldesc_t) * dma_desc_ct, MALLOC_CAP_DMA); if (!spihost[host]->dmadesc_tx || !spihost[host]->dmadesc_rx) goto nomem; } else { //We're limited to non-DMA transfers: the SPI work registers can hold 64 bytes at most. spihost[host]->max_transfer_sz = 16 * 4; } //Create queues spihost[host]->trans_queue = xQueueCreate(slave_config->queue_size, sizeof(spi_slave_transaction_t *)); spihost[host]->ret_queue = xQueueCreate(slave_config->queue_size, sizeof(spi_slave_transaction_t *)); if (!spihost[host]->trans_queue || !spihost[host]->ret_queue) goto nomem; esp_intr_alloc(spicommon_irqsource_for_host(host), ESP_INTR_FLAG_INTRDISABLED, spi_intr, (void *)spihost[host], &spihost[host]->intr); spihost[host]->hw = spicommon_hw_for_host(host); //Configure slave spihost[host]->hw->clock.val = 0; spihost[host]->hw->user.val = 0; spihost[host]->hw->ctrl.val = 0; spihost[host]->hw->slave.wr_rd_buf_en = 1; //no sure if needed spihost[host]->hw->user.doutdin = 1; //we only support full duplex spihost[host]->hw->user.sio = 0; spihost[host]->hw->slave.slave_mode = 1; spihost[host]->hw->dma_conf.val |= SPI_OUT_RST | SPI_IN_RST | SPI_AHBM_RST | SPI_AHBM_FIFO_RST; spihost[host]->hw->dma_out_link.start = 0; spihost[host]->hw->dma_in_link.start = 0; spihost[host]->hw->dma_conf.val &= ~(SPI_OUT_RST | SPI_IN_RST | SPI_AHBM_RST | SPI_AHBM_FIFO_RST); spihost[host]->hw->dma_conf.out_data_burst_en = 1; spihost[host]->hw->slave.sync_reset = 1; spihost[host]->hw->slave.sync_reset = 0; bool nodelay = true; spihost[host]->hw->ctrl.rd_bit_order = (slave_config->flags & SPI_SLAVE_RXBIT_LSBFIRST) ? 1 : 0; spihost[host]->hw->ctrl.wr_bit_order = (slave_config->flags & SPI_SLAVE_TXBIT_LSBFIRST) ? 1 : 0; if (slave_config->mode == 0) { spihost[host]->hw->pin.ck_idle_edge = 0; spihost[host]->hw->user.ck_i_edge = 1; spihost[host]->hw->ctrl2.miso_delay_mode = nodelay ? 0 : 2; } else if (slave_config->mode == 1) { spihost[host]->hw->pin.ck_idle_edge = 0; spihost[host]->hw->user.ck_i_edge = 0; spihost[host]->hw->ctrl2.miso_delay_mode = nodelay ? 0 : 1; } else if (slave_config->mode == 2) { spihost[host]->hw->pin.ck_idle_edge = 1; spihost[host]->hw->user.ck_i_edge = 0; spihost[host]->hw->ctrl2.miso_delay_mode = nodelay ? 0 : 1; } else if (slave_config->mode == 3) { spihost[host]->hw->pin.ck_idle_edge = 1; spihost[host]->hw->user.ck_i_edge = 1; spihost[host]->hw->ctrl2.miso_delay_mode = nodelay ? 0 : 2; } //Reset DMA spihost[host]->hw->dma_conf.val |= SPI_OUT_RST | SPI_IN_RST | SPI_AHBM_RST | SPI_AHBM_FIFO_RST; spihost[host]->hw->dma_out_link.start = 0; spihost[host]->hw->dma_in_link.start = 0; spihost[host]->hw->dma_conf.val &= ~(SPI_OUT_RST | SPI_IN_RST | SPI_AHBM_RST | SPI_AHBM_FIFO_RST); //Disable unneeded ints spihost[host]->hw->slave.rd_buf_done = 0; spihost[host]->hw->slave.wr_buf_done = 0; spihost[host]->hw->slave.rd_sta_done = 0; spihost[host]->hw->slave.wr_sta_done = 0; spihost[host]->hw->slave.rd_buf_inten = 0; spihost[host]->hw->slave.wr_buf_inten = 0; spihost[host]->hw->slave.rd_sta_inten = 0; spihost[host]->hw->slave.wr_sta_inten = 0; //Force a transaction done interrupt. This interrupt won't fire yet because we initialized the SPI interrupt as //disabled. This way, we can just enable the SPI interrupt and the interrupt handler will kick in, handling //any transactions that are queued. spihost[host]->hw->slave.trans_inten = 1; spihost[host]->hw->slave.trans_done = 1; return ESP_OK; nomem: if (spihost[host]) { if (spihost[host]->trans_queue) vQueueDelete(spihost[host]->trans_queue); if (spihost[host]->ret_queue) vQueueDelete(spihost[host]->ret_queue); free(spihost[host]->dmadesc_tx); free(spihost[host]->dmadesc_rx); } free(spihost[host]); spihost[host] = NULL; spicommon_periph_free(host); return ESP_ERR_NO_MEM; }
int main(int argc, char* argv[]) { int i = 0; // indice usato per i cicli for int n = 0; // variabile per il numero di sensori xQueueHandle queue[NUM_PRIORITIES]; Sync_Init sync_sensor; initNode(); initSensors(); // initNetwork(); funzione fornita dal livello rete if ( join(getID()) == 0) { // supponendo sia questa la firma // scrive nel log che si e' verificato un errore di autenticazione while(1); } for (i = 0; i < NUM_PRIORITIES; i++) queue[i] = xQueueCreate(MAX_QUEUE_LENGTH, sizeof(Message)); if (xTaskCreate(asyncRequestManage,// nome della funzione "Gestione richieste asincrone", configMINIMAL_STACK_SIZE, queue(1), // parametri della funzione: queue(1) 3) != pdTRUE) { // scrive nel log che si `e verificato un errore di gestione della memoria while(1); } n = getNumSensors(); for (i = 0; i < n; i++) { if (getPeriod(getSensorID(i)) > 0) { sync_sensor.ID = getSensorID(i); sync_sensor.period = getPeriod(getSensorID(i)); if (xTaskCreate(syncSensorManage,// nome della funzione "Task di gestione di un sensore sincrono ", configMINIMAL_STACK_SIZE, (void *)&sync_sensor, // parametri della funzione 2) != pdTRUE) { // scrive nel log che si `e verificato un errore di gestione della memoria while(1); } } } if (xTaskCreate(sendOverNetwork,// nome della funzione "Task per l'invio dei messaggi", configMINIMAL_STACK_SIZE, (void *)queue, // parametri della funzione 1) != pdTRUE) { // scrive nel log che si `e verificato un errore di gestione della memoria while(1); } vTaskStartScheduler(); while (1); }
/******************************************************************** * * * U5_Open * * * ********************************************************************* INPUT : uint32_t speed : baudrate uint16_t ft : frame type see FRAME_TYPE_enum uint16_t pt : parity type see PARITY_TYPE_enum ********************************************************************* * * * Open the serial port for DTE comunications * * * ********************************************************************/ void U5_Open(uint32_t speed,uint16_t parity,uint16_t stopbits) { USART_InitTypeDef USART_InitStructure; U5_Close() ; switch(stopbits) { case UARTSB_1: stopbits = USART_StopBits_1; break; case UARTSB_2: stopbits = USART_StopBits_2; break; default: return; } switch(parity) { case UARTP_None: mask_U5 = 0xff; parity = USART_Parity_No; break; case UARTP_Even: mask_U5 = 0x7f; parity = USART_Parity_Even; break; case UARTP_Odd: mask_U5 = 0x7f; parity = USART_Parity_Odd; break; default: return; } //set Baud Rate USART_InitStructure.USART_BaudRate = speed ; // UART5 parameters overtake configuration ---------------------------- /* UART5 configured as follow: - BaudRate = 115200 baud - Word Length = 8 Bits - One Stop Bit - No parity - Hardware flow control enabled (RTS and CTS signals) - Receive and transmit enabled */ USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_Parity = parity ; USART_InitStructure.USART_StopBits = stopbits; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // configure the UART5 USART_Init(UART5, &USART_InitStructure); /* Configure UART5 Rx (PD.2) as input floating */ GpioInit(GPIOD,GPIO_Pin_2,GPIO_Mode_IN_FLOATING,0); /* Configure UART5 Tx (PC.12) as alternate function push-pull */ GpioInit(GPIOC,GPIO_Pin_12,GPIO_Mode_AF_PP,0); if (!xRxQueue) xRxQueue = xQueueCreate( RxQueueSize, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); if (!xTxQueue) xTxQueue = xQueueCreate( TxQueueSize, ( unsigned portBASE_TYPE ) sizeof( signed portCHAR ) ); if (!prntfBuf) prntfBuf = pvPortMalloc(PRNTFBUF_SIZE); if (!xSemaPrintf) xSemaPrintf = xSemaphoreCreateMutex(); // Enable UART5 USART_Cmd(UART5, ENABLE); U5_ClearTx(); U5_ClearRx(); NVIC_SetPriority(UART5_IRQn,UART5_IRQ_PRIO); // Enable IRQ NVIC_EnableIRQ(UART5_IRQn); active_U5 = TRUE; }
static void prvCreateAndDeleteStaticallyAllocatedQueues( void ) { QueueHandle_t xQueue; /* StaticQueue_t is a publicly accessible structure that has the same size and alignment requirements as the real queue structure. It is provided as a mechanism for applications to know the size of the queue (which is dependent on the architecture and configuration file settings) without breaking the strict data hiding policy by exposing the real queue internals. This StaticQueue_t variable is passed into the xQueueCreateStatic() function calls within this function. */ static StaticQueue_t xStaticQueue; /* The queue storage area must be large enough to hold the maximum number of items it is possible for the queue to hold at any one time, which equals the queue length (in items, not bytes) multiplied by the size of each item. In this case the queue will hold staticQUEUE_LENGTH_IN_ITEMS 64-bit items. See http://www.freertos.org/Embedded-RTOS-Queues.html */ static uint8_t ucQueueStorageArea[ staticQUEUE_LENGTH_IN_ITEMS * sizeof( uint64_t ) ]; /* Create the queue. xQueueCreateStatic() has two more parameters than the usual xQueueCreate() function. The first new parameter is a pointer to the pre-allocated queue storage area. The second new parameter is a pointer to the StaticQueue_t structure that will hold the queue state information in an anonymous way. If the two pointers are passed as NULL then the data will be allocated dynamically as if xQueueCreate() had been called. */ xQueue = xQueueCreateStatic( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */ sizeof( uint64_t ), /* The size of each item. */ ucQueueStorageArea, /* The buffer used to hold items within the queue. */ &xStaticQueue ); /* The static queue structure that will hold the state of the queue. */ /* The queue handle should equal the static queue structure passed into the xQueueCreateStatic() function. */ configASSERT( xQueue == ( QueueHandle_t ) &xStaticQueue ); /* Ensure the queue passes a few sanity checks as a valid queue. */ prvSanityCheckCreatedQueue( xQueue ); /* Delete the queue again so the buffers can be reused. */ vQueueDelete( xQueue ); /* Now do the same using a dynamically allocated queue to ensure the delete function is working correctly in both the static and dynamic memory allocation cases. */ #if( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) { xQueue = xQueueCreate( staticQUEUE_LENGTH_IN_ITEMS, /* The maximum number of items the queue can hold. */ sizeof( uint64_t ) ); /* The size of each item. */ /* The queue handle should equal the static queue structure passed into the xQueueCreateStatic() function. */ configASSERT( xQueue != NULL ); /* Ensure the queue passes a few sanity checks as a valid queue. */ prvSanityCheckCreatedQueue( xQueue ); /* Delete the queue again so the buffers can be reused. */ vQueueDelete( xQueue ); } #endif }
csp_queue_handle_t csp_queue_create(int length, size_t item_size) { return xQueueCreate(length, item_size); }
// *************** vOLEDTask *************** void vOLEDTask( void *pvParameters ) { xOLEDMessage xMessage; unsigned portLONG ulY, ulMaxY; // unsigned portBASE_TYPE uxUnusedStackOnEntry; /* Functions to access the OLED. The one used depends on the dev kit being used. */ void ( *vOLEDInit )( unsigned portLONG ) = NULL; void ( *vOLEDStringDraw )( const portCHAR *, unsigned portLONG, unsigned portLONG, unsigned portCHAR ) = NULL; void ( *vOLEDImageDraw )( const unsigned portCHAR *, unsigned portLONG, unsigned portLONG, unsigned portLONG, unsigned portLONG ) = NULL; void ( *vOLEDClear )( void ) = NULL; /* Create the queue used by the OLED task. Messages for display on the OLED are received via this queue. */ xOLEDQueue = xQueueCreate( mainOLED_QUEUE_SIZE, sizeof( xOLEDMessage ) ); /* Get the "high water mark" for this thread's stack. This value indicates the smallest amount of unused stack reached for this thread. A value of 0 means the thread has either filled or overflowed its stack. Note that this function call is for demo only and serves no purpose here. */ // uxUnusedStackOnEntry = uxTaskGetStackHighWaterMark( NULL ); /* Map the OLED access functions to the driver functions that are appropriate for the evaluation kit being used. */ switch( HWREG( SYSCTL_DID1 ) & SYSCTL_DID1_PRTNO_MASK ) { // case SYSCTL_DID1_PRTNO_6965 : // case SYSCTL_DID1_PRTNO_2965 : vOLEDInit = OSRAM128x64x4Init; // vOLEDStringDraw = OSRAM128x64x4StringDraw; // vOLEDImageDraw = OSRAM128x64x4ImageDraw; // vOLEDClear = OSRAM128x64x4Clear; // ulMaxY = mainMAX_ROWS_64; // break; // case SYSCTL_DID1_PRTNO_1968 : case SYSCTL_DID1_PRTNO_8962 : default : vOLEDInit = RIT128x96x4Init; vOLEDStringDraw = RIT128x96x4StringDraw; vOLEDImageDraw = RIT128x96x4ImageDraw; vOLEDClear = RIT128x96x4Clear; ulMaxY = mainMAX_ROWS_96; break; // default : vOLEDInit = vFormike128x128x16Init; // vOLEDStringDraw = vFormike128x128x16StringDraw; // vOLEDImageDraw = vFormike128x128x16ImageDraw; // vOLEDClear = vFormike128x128x16Clear; // ulMaxY = mainMAX_ROWS_128; // break; } ulY = ulMaxY; /* Initialise the OLED and display a startup message. */ vOLEDInit( ulSSI_FREQUENCY ); vOLEDStringDraw( "POWERED BY FreeRTOS", 0, 0, mainFULL_SCALE ); for( ;; ) { /* Wait for a message to arrive that requires displaying. */ xQueueReceive( xOLEDQueue, &xMessage, portMAX_DELAY ); /* Write the message on the next available row. */ ulY += mainCHARACTER_HEIGHT; if( ulY >= ulMaxY ) { ulY = mainCHARACTER_HEIGHT; vOLEDClear(); //vOLEDStringDraw( pcWelcomeMessage, 0, 0, mainFULL_SCALE ); } /* Display the message along with the maximum jitter time from the high priority time test. */ vOLEDStringDraw( xMessage.pcMessage, 0, ulY, mainFULL_SCALE ); } }
//AFIO->MAPR=(AFIO->MAPR|AFIO_MAPR_CAN_REMAP_0|AFIO_MAPR_CAN_REMAP_1)&AFIO_MAPR_CAN_REMAP_0; void Serial_Configuration(unsigned int brate) { #ifdef USE_INT NVIC_InitTypeDef NVIC_InitStructure; #endif GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE); GPIO_InitStructure.GPIO_Pin = USART_TXD_PIN ; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(USART_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = USART_RXD_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//更具外部电路是否有上下拉电阻需要改变 GPIO_Init(USART_GPIO, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = USART_RTS_PIN; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//RTS应该配置为推挽输出,配置为AF时会因为没有配置流控制而不起作用 GPIO_Init(USART_GPIO, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = brate; //波特率115200 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //字长8位 USART_InitStructure.USART_StopBits = USART_StopBits_1; //1位停止字节 USART_InitStructure.USART_Parity = USART_Parity_No; //无奇偶校验 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无流控制 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//打开Rx接收和Tx发送功能 USART_Init(USART_PORT, &USART_InitStructure);//初始化USART #ifdef USE_INT USART_ITConfig(USART_PORT, USART_IT_RXNE, ENABLE); // 使能指定的USART1接收中断 USART_ITConfig(USART_PORT, USART_IT_TXE, DISABLE); // 失能指定的USART1发送中断 USART_ITConfig(USART_PORT, USART_IT_TC, ENABLE); // 失能指定的USART1发送完成中断 USART_ClearITPendingBit(USART1, USART_IT_TC); USART_ClearITPendingBit(USART1, USART_IT_RXNE); NVIC_InitStructure.NVIC_IRQChannel = USART_NVIC_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = UART_PRI; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); xRxedChars = xQueueCreate( serialRxQueueLength, sizeof(u8 ) ); xCharsForTx = xQueueCreate( serialTxQueueLength , sizeof(u8 ) ); if(xRxedChars != NULL){ printf("xRxedChars created OK ! \r\n"); } if(xCharsForTx != NULL){ printf("xCharsForTx created OK ! \r\n"); } xSem_UART_CMD = xSemaphoreCreateCounting(2,0); if( xSem_UART_CMD != NULL ) { printf("xSem_UART_CMD created OK ! \r\n"); } #endif USART_Cmd(USART_PORT, ENABLE);//启动串口 USART_CON_TORECV; }
//***************************************************************************** // // Completes the initialization of lwIP. This is directly called when not // using a RTOS and provided as a callback to the TCP/IP thread when using a // RTOS. // //***************************************************************************** static void lwIPPrivateInit(void *pvArg) { struct ip_addr ip_addr; struct ip_addr net_mask; struct ip_addr gw_addr; // // If not using a RTOS, initialize the lwIP stack. // #if NO_SYS lwip_init(); #endif // // If using a RTOS, create a queue (to be used as a semaphore) to signal // the Ethernet interrupt task from the Ethernet interrupt handler. // #if !NO_SYS xQueueCreate(g_pcQueueMem, sizeof(g_pcQueueMem), 1, sizeof(void *), &g_pInterrupt); #endif // // If using a RTOS, create the Ethernet interrupt task. // #if !NO_SYS xTaskCreate(lwIPInterruptTask, (signed portCHAR *)"eth_int", (signed portCHAR *)g_pulStack, sizeof(g_pulStack), 0, 1, 0); #endif // // Setup the network address values. // if(g_ulIPMode == IPADDR_USE_STATIC) { ip_addr.addr = htonl(g_ulIPAddr); net_mask.addr = htonl(g_ulNetMask); gw_addr.addr = htonl(g_ulGWAddr); } else { ip_addr.addr = 0; net_mask.addr = 0; gw_addr.addr = 0; } // // Create, configure and add the Ethernet controller interface with // default settings. ip_input should be used to send packets directly to // the stack when not using a RTOS and tcpip_input should be used to send // packets to the TCP/IP thread's queue when using a RTOS. // #if NO_SYS netif_add(&g_sNetIF, &ip_addr, &net_mask, &gw_addr, NULL, stellarisif_init, ip_input); #else netif_add(&g_sNetIF, &ip_addr, &net_mask, &gw_addr, NULL, stellarisif_init, tcpip_input); #endif netif_set_default(&g_sNetIF); // // Start DHCP, if enabled. // #if LWIP_DHCP if(g_ulIPMode == IPADDR_USE_DHCP) { dhcp_start(&g_sNetIF); } #endif // // Start AutoIP, if enabled and DHCP is not. // #if LWIP_AUTOIP if(g_ulIPMode == IPADDR_USE_AUTOIP) { autoip_start(&g_sNetIF); } #endif // // Bring the interface up. // netif_set_up(&g_sNetIF); // // Setup a timeout for the host timer callback function if using a RTOS. // #if !NO_SYS && HOST_TMR_INTERVAL sys_timeout(HOST_TMR_INTERVAL, lwIPPrivateHostTimer, NULL); #endif // // If not running on a Fury-class device, then MDIX is handled in software. // In this case, when using a RTOS, setup a timeout for the soft-MDIX // handler. // #if !NO_SYS if(!CLASS_IS_FURY) { sys_timeout(SOFT_MDIX_INTERVAL, lwIPSoftMDIXTimer, NULL); } #endif }
bool CAN_init(can_t can, uint32_t baudrate_kbps, uint16_t rxq_size, uint16_t txq_size, can_void_func_t bus_off_cb, can_void_func_t data_ovr_cb) { if (!CAN_VALID(can)){ return false; } can_struct_t *pStruct = CAN_STRUCT_PTR(can); LPC_CAN_TypeDef *pCAN = pStruct->pCanRegs; bool failed = true; /* Enable CAN Power, and select the PINS * CAN1 is at P0.0, P0.1 and P0.21, P0.22 * CAN2 is at P0.4, P0.5 and P2.7, P2.8 * On SJ-One board, we have P0.0, P0.1, and P2.7, P2.8 */ if (can1 == can) { LPC_SC->PCONP |= can1_pconp_mask; LPC_PINCON->PINSEL0 &= ~(0xF << 0); LPC_PINCON->PINSEL0 |= (0x5 << 0); } else if (can2 == can){ LPC_SC->PCONP |= can2_pconp_mask; LPC_PINCON->PINSEL4 &= ~(0xF << 14); LPC_PINCON->PINSEL4 |= (0x5 << 14); } /* Create the queues with minimum size of 1 to avoid NULL pointer reference */ if (!pStruct->rxQ) { pStruct->rxQ = xQueueCreate(rxq_size ? rxq_size : 1, sizeof(can_msg_t)); } if (!pStruct->txQ) { pStruct->txQ = xQueueCreate(txq_size ? txq_size : 1, sizeof(can_msg_t)); } /* The CAN dividers must all be the same for both CANs * Set the dividers of CAN1, CAN2, ACF to CLK / 1 */ lpc_pclk(pclk_can1, clkdiv_1); lpc_pclk(pclk_can2, clkdiv_1); lpc_pclk(pclk_can_flt, clkdiv_1); pCAN->MOD = can_mod_reset; pCAN->IER = 0x0; // Disable All CAN Interrupts pCAN->GSR = 0x0; // Clear error counters pCAN->CMR = 0xE; // Abort Tx, release Rx, clear data over-run /** * About the AFMR register : * B0 B1 * Filter Mode | AccOff bit | AccBP bit | CAN Rx interrupt * Off Mode 1 0 No messages accepted * Bypass Mode X 1 All messages accepted * FullCAN 0 0 HW acceptance filtering */ LPC_CANAF->AFMR = afmr_disabled; // Clear pending interrupts and the CAN Filter RAM LPC_CANAF_RAM->mask[0] = pCAN->ICR; memset((void*)&(LPC_CANAF_RAM->mask[0]), 0, sizeof(LPC_CANAF_RAM->mask)); /* Zero out the filtering registers */ LPC_CANAF->SFF_sa = 0; LPC_CANAF->SFF_GRP_sa = 0; LPC_CANAF->EFF_sa = 0; LPC_CANAF->EFF_GRP_sa = 0; LPC_CANAF->ENDofTable = 0; /* Do not accept any messages until CAN filtering is enabled */ LPC_CANAF->AFMR = afmr_disabled; /* Set the baud-rate. You can verify the settings by visiting: * http://www.kvaser.com/en/support/bit-timing-calculator.html */ do { const uint32_t baudDiv = sys_get_cpu_clock() / (1000 * baudrate_kbps); const uint32_t SJW = 3; const uint32_t SAM = 0; uint32_t BRP = 0, TSEG1 = 0, TSEG2 = 0, NT = 0; /* Calculate suitable nominal time value * NT (nominal time) = (TSEG1 + TSEG2 + 3) * NT <= 24 * TSEG1 >= 2*TSEG2 */ failed = true; for(NT=24; NT > 0; NT-=2) { if ((baudDiv % NT)==0) { BRP = baudDiv / NT - 1; NT--; TSEG2 = (NT/3) - 1; TSEG1 = NT -(NT/3) - 1; failed = false; break; } } if (!failed) { pCAN->BTR = (SAM << 23) | (TSEG2<<20) | (TSEG1<<16) | (SJW<<14) | BRP; // CANx->BTR = 0x002B001D; // 48Mhz 100Khz } } while (0); /* If everything okay so far, enable the CAN interrupts */ if (!failed) { /* At minimum, we need Rx/Tx interrupts */ pCAN->IER = (intr_rx | intr_all_tx); /* Enable BUS-off interrupt and callback if given */ if (bus_off_cb) { pStruct->bus_error = bus_off_cb; pCAN->IER |= g_can_bus_err_intr; } /* Enable data-overrun interrupt and callback if given */ if (data_ovr_cb) { pStruct->data_overrun = data_ovr_cb; pCAN->IER |= intr_ovrn; } /* Finally, enable the actual CPU core interrupt */ vTraceSetISRProperties(CAN_IRQn, "CAN", IP_can); NVIC_EnableIRQ(CAN_IRQn); } /* return true if all is well */ return (false == failed); }
ThreadQueue(UBaseType_t max_size) { queue = xQueueCreate(max_size, sizeof(TaskHandle_t)); }
//Initialize I2S subsystem for DMA circular buffer use void ICACHE_FLASH_ATTR i2sInit() { int x, y; underrunCnt=0; //First, take care of the DMA buffers. for (y=0; y<I2SDMABUFCNT; y++) { //Allocate memory for this DMA sample buffer. i2sBuf[y]=malloc(I2SDMABUFLEN*4); //Clear sample buffer. We don't want noise. for (x=0; x<I2SDMABUFLEN; x++) { i2sBuf[y][x]=0; } } //Reset DMA SET_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST|SLC_TXLINK_RST); CLEAR_PERI_REG_MASK(SLC_CONF0, SLC_RXLINK_RST|SLC_TXLINK_RST); //Clear DMA int flags SET_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff); CLEAR_PERI_REG_MASK(SLC_INT_CLR, 0xffffffff); //Enable and configure DMA CLEAR_PERI_REG_MASK(SLC_CONF0, (SLC_MODE<<SLC_MODE_S)); SET_PERI_REG_MASK(SLC_CONF0,(1<<SLC_MODE_S)); SET_PERI_REG_MASK(SLC_RX_DSCR_CONF,SLC_INFOR_NO_REPLACE|SLC_TOKEN_NO_REPLACE); CLEAR_PERI_REG_MASK(SLC_RX_DSCR_CONF, SLC_RX_FILL_EN|SLC_RX_EOF_MODE | SLC_RX_FILL_MODE); //Initialize DMA buffer descriptors in such a way that they will form a circular //buffer. for (x=0; x<I2SDMABUFCNT; x++) { i2sBufDesc[x].owner=1; i2sBufDesc[x].eof=1; i2sBufDesc[x].sub_sof=0; i2sBufDesc[x].datalen=I2SDMABUFLEN*4; i2sBufDesc[x].blocksize=I2SDMABUFLEN*4; i2sBufDesc[x].buf_ptr=(uint32_t)&i2sBuf[x][0]; i2sBufDesc[x].unused=0; i2sBufDesc[x].next_link_ptr=(int)((x<(I2SDMABUFCNT-1))?(&i2sBufDesc[x+1]):(&i2sBufDesc[0])); } //Feed dma the 1st buffer desc addr //To send data to the I2S subsystem, counter-intuitively we use the RXLINK part, not the TXLINK as you might //expect. The TXLINK part still needs a valid DMA descriptor, even if it's unused: the DMA engine will throw //an error at us otherwise. Just feed it any random descriptor. CLEAR_PERI_REG_MASK(SLC_TX_LINK,SLC_TXLINK_DESCADDR_MASK); SET_PERI_REG_MASK(SLC_TX_LINK, ((uint32)&i2sBufDesc[1]) & SLC_TXLINK_DESCADDR_MASK); //any random desc is OK, we don't use TX but it needs something valid CLEAR_PERI_REG_MASK(SLC_RX_LINK,SLC_RXLINK_DESCADDR_MASK); SET_PERI_REG_MASK(SLC_RX_LINK, ((uint32)&i2sBufDesc[0]) & SLC_RXLINK_DESCADDR_MASK); //Attach the DMA interrupt _xt_isr_attach(ETS_SLC_INUM, (_xt_isr)slc_isr, NULL); //Enable DMA operation intr WRITE_PERI_REG(SLC_INT_ENA, SLC_RX_EOF_INT_ENA); //clear any interrupt flags that are set WRITE_PERI_REG(SLC_INT_CLR, 0xffffffff); ///enable DMA intr in cpu _xt_isr_unmask(1<<ETS_SLC_INUM); //We use a queue to keep track of the DMA buffers that are empty. The ISR will push buffers to the back of the queue, //the mp3 decode will pull them from the front and fill them. For ease, the queue will contain *pointers* to the DMA //buffers, not the data itself. The queue depth is one smaller than the amount of buffers we have, because there's //always a buffer that is being used by the DMA subsystem *right now* and we don't want to be able to write to that //simultaneously. dmaQueue=xQueueCreate(I2SDMABUFCNT-1, sizeof(int*)); //Start transmission SET_PERI_REG_MASK(SLC_TX_LINK, SLC_TXLINK_START); SET_PERI_REG_MASK(SLC_RX_LINK, SLC_RXLINK_START); //---- //Init pins to i2s functions PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_I2SO_DATA); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_I2SO_WS); #ifndef USE_ESP01_MODULE PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_I2SO_BCK); #else GPIO_AS_INPUT(1<<15); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_GPIO15); #endif //Enable clock to i2s subsystem i2c_writeReg_Mask_def(i2c_bbpll, i2c_bbpll_en_audio_clock_out, 1); //Reset I2S subsystem CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK); SET_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK); CLEAR_PERI_REG_MASK(I2SCONF,I2S_I2S_RESET_MASK); //Select 16bits per channel (FIFO_MOD=0), no DMA access (FIFO only) CLEAR_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN|(I2S_I2S_RX_FIFO_MOD<<I2S_I2S_RX_FIFO_MOD_S)|(I2S_I2S_TX_FIFO_MOD<<I2S_I2S_TX_FIFO_MOD_S)); //Enable DMA in i2s subsystem SET_PERI_REG_MASK(I2S_FIFO_CONF, I2S_I2S_DSCR_EN); //tx/rx binaureal CLEAR_PERI_REG_MASK(I2SCONF_CHAN, (I2S_TX_CHAN_MOD<<I2S_TX_CHAN_MOD_S)|(I2S_RX_CHAN_MOD<<I2S_RX_CHAN_MOD_S)); //Clear int SET_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_TX_REMPTY_INT_CLR|I2S_I2S_TX_WFULL_INT_CLR| I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR); CLEAR_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_TX_REMPTY_INT_CLR|I2S_I2S_TX_WFULL_INT_CLR| I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR); //trans master&rece slave,MSB shift,right_first,msb right CLEAR_PERI_REG_MASK(I2SCONF, I2S_TRANS_SLAVE_MOD| (I2S_BITS_MOD<<I2S_BITS_MOD_S)| (I2S_BCK_DIV_NUM <<I2S_BCK_DIV_NUM_S)| (I2S_CLKM_DIV_NUM<<I2S_CLKM_DIV_NUM_S)); SET_PERI_REG_MASK(I2SCONF, I2S_RIGHT_FIRST|I2S_MSB_RIGHT|I2S_RECE_SLAVE_MOD| I2S_RECE_MSB_SHIFT|I2S_TRANS_MSB_SHIFT| ((16&I2S_BCK_DIV_NUM )<<I2S_BCK_DIV_NUM_S)| ((7&I2S_CLKM_DIV_NUM)<<I2S_CLKM_DIV_NUM_S)); //No idea if ints are needed... //clear int SET_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_TX_REMPTY_INT_CLR|I2S_I2S_TX_WFULL_INT_CLR| I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR); CLEAR_PERI_REG_MASK(I2SINT_CLR, I2S_I2S_TX_REMPTY_INT_CLR|I2S_I2S_TX_WFULL_INT_CLR| I2S_I2S_RX_WFULL_INT_CLR|I2S_I2S_PUT_DATA_INT_CLR|I2S_I2S_TAKE_DATA_INT_CLR); //enable int SET_PERI_REG_MASK(I2SINT_ENA, I2S_I2S_TX_REMPTY_INT_ENA|I2S_I2S_TX_WFULL_INT_ENA| I2S_I2S_RX_REMPTY_INT_ENA|I2S_I2S_TX_PUT_DATA_INT_ENA|I2S_I2S_RX_TAKE_DATA_INT_ENA); //Start transmission SET_PERI_REG_MASK(I2SCONF,I2S_I2S_TX_START); }
int os_queue_create(os_queue_t* queue, size_t item_size, size_t item_count) { *queue = xQueueCreate(item_count, item_size); return *queue==NULL; }
int main( void ) { // Init the semi-hosting. printf( "\n" ); // DAC/DMA Setup NVIC_DisableIRQ( DMA_IRQn); InitializeDAC(); InitializeDMA(); /* Instantiate queue and semaphores */ xQueueToneInput = xQueueCreate( DTMF_REQ_QUEUE_SIZE, sizeof( char ) ); xQueueDMARequest = xQueueCreate( DMA_REQ_QUEUE_SIZE, sizeof( DAC_Setup_Message )); xIoQueue = xQueueCreate(16,sizeof(char)); dacResponseHandle = xQueueCreate( DMA_COMP_QUEUE_SIZE, sizeof( DAC_Complete_Message ) ); sampQ = xQueueCreate( 1, sizeof(DTMFSampleType *) ); resultQ = xQueueCreate( 1, sizeof(struct DTMFResult_t) ); lQueues.xIoInputQueue = xQueueCreate( 2, sizeof(xData) ); lQueues.xDACQueue = xQueueToneInput; if( sampQ != NULL && resultQ != NULL && xQueueToneInput != NULL && xQueueDMARequest != NULL && dacResponseHandle != NULL && lQueues.xIoInputQueue != NULL && lQueues.xDACQueue != NULL) { xTaskCreate( vTaskToneGenerator, /* Pointer to the function that implements the task. */ "ToneGenerator", /* Text name for the task. This is to facilitate debugging only. */ 240, /* Stack depth in words. */ NULL, /* No input data */ configMAX_PRIORITIES-2, /* This task will run at priority 1. */ NULL ); /* We are not using the task handle. */ #ifdef TONEGEN_INPUT_UNIT_TEST xTaskCreate( vTaskToneRequestTest, "ToneRequestTest", 240, NULL, configMAX_PRIORITIES-2/*4*/, NULL ); #endif #ifdef TONEGEN_DMA_UNIT_TEST xTaskCreate( vTaskDMAHandlerTest, "DMAHandlerTest", 240, NULL, 2, NULL ); #else //============================================================================ // Create DAC and DMA Tasks //============================================================================ xTaskCreate( DAC_Handler,/* Pointer to the function that implements the task. */ "DAC", /* Text name for the task. This is to facilitate debugging only. */ 240, /* Stack depth in words. */ (void*)xQueueDMARequest, /* Pass the text to be printed in as the task parameter. */ configMAX_PRIORITIES-1, /* This task will run at highest priority. */ NULL ); /* We are not using the task handle. */ #endif xTaskCreate( vAdcTask, "tADC", 240, (void *)sampQ, 2, NULL ); #ifdef __DTMF_PERF__ TestBenchTaskParam.sampQ = sampQ; TestBenchTaskParam.resultQ = resultQ; xTaskCreate( vTestBenchTask, "tTB", 500, (void *)&TestBenchTaskParam, 3, NULL ); #endif DTMFDetectTaskParam.sampQ = sampQ; DTMFDetectTaskParam.resultQ = resultQ; xTaskCreate( vDTMFDetectTask, "tDetect", 500, (void *)&DTMFDetectTaskParam, configMAX_PRIORITIES-3, NULL ); xTaskCreate( uart_tx_handler, "Tx Task", 500, NULL, 2, NULL ); xTaskCreate( uart_rx_handler, "Rx Task", 500, NULL, 2, NULL ); uart_configure(); /* Create four instances of the task that will write to the queue */ xTaskCreate( gpioInterfaceTask, "Keypad_Task", 240, &xIoQueue, configMAX_PRIORITIES-1, NULL); xTaskCreate( vIoRxTask, "IO_Receiver", 240, NULL, configMAX_PRIORITIES-1, NULL ); /* Start the scheduler so our tasks start executing. */ vTaskStartScheduler(); } /* If all is well we will never reach here as the scheduler will now be running. If we do reach here then it is likely that there was insufficient heap available for the idle task to be created. */ for( ;; ); return 0; }
void start() { adc = hal::get_driver<Adc>(hal::SENSOR_ADC); mux = hal::get_driver<Cd74hc4067>(hal::CD74HC4067); xTaskCreate(task_loop, "sensor task", 400, NULL, 2, &task_handle); event_queue = xQueueCreate(EVENT_QUEUE_DEPTH, sizeof(AdcEvent)); }
/** * Creates a new semaphore. * * @param count is non-zero if the semaphore should be acquired initially. * @return the handle of the created semaphore. */ sys_sem_t sys_sem_new(u8_t count) { xQueueHandle sem; void *temp; u32_t i; /* Find a semaphore that is not in use. */ for(i = 0; i < SYS_SEM_MAX; i++) { if(sems[i].queue == 0) { break; } } if(i == SYS_SEM_MAX) { #if SYS_STATS STATS_INC(sys.sem.err); #endif /* SYS_STATS */ return 0; } /* Create a single-entry queue to act as a semaphore. */ #if RTOS_SAFERTOS if(xQueueCreate(sems[i].buffer, sizeof(sems[0].buffer), 1, sizeof(void *), &sem) != pdPASS) { #elif RTOS_FREERTOS sem = xQueueCreate(1, sizeof(void *)); if(sem == NULL) { #endif /* RTOS_SAFERTOS */ #if SYS_STATS STATS_INC(sys.sem.err); #endif /* SYS_STATS */ return 0; } /* Acquired the semaphore if necessary. */ if(count == 0) { temp = 0; xQueueSend(sem, &temp, 0); } /* Update the semaphore statistics. */ #if SYS_STATS STATS_INC(sys.sem.used); #if LWIP_STATS if(lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) { lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; } #endif #endif /* SYS_STATS */ /* Save the queue handle. */ sems[i].queue = sem; /* Return this semaphore. */ return &(sems[i]); } /** * Signal a semaphore. * * @param sem is the semaphore to signal. */ void sys_sem_signal(sys_sem_t sem) { void *msg; /* Receive a message from the semaphore's queue. */ xQueueReceive(sem->queue, &msg, 0); }
static void prvQueueOverwriteTask( void *pvParameters ) { QueueHandle_t xTaskQueue; const UBaseType_t uxQueueLength = 1; uint32_t ulValue, ulStatus = pdPASS, x; /* The parameter is not used. */ ( void ) pvParameters; /* Create the queue. xQueueOverwrite() should only be used on queues that have a length of 1. */ xTaskQueue = xQueueCreate( uxQueueLength, ( UBaseType_t ) sizeof( uint32_t ) ); configASSERT( xTaskQueue ); for( ;; ) { /* The queue is empty. Writing to the queue then reading from the queue should return the item written. */ ulValue = 10; xQueueOverwrite( xTaskQueue, &ulValue ); ulValue = 0; xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK ); if( ulValue != 10 ) { ulStatus = pdFAIL; } /* Now try writing to the queue several times. Each time the value in the queue should get overwritten. */ for( x = 0; x < qoLOOPS; x++ ) { /* Write to the queue. */ xQueueOverwrite( xTaskQueue, &x ); /* Check the value in the queue is that written, even though the queue was not necessarily empty. */ xQueuePeek( xTaskQueue, &ulValue, qoDONT_BLOCK ); if( ulValue != x ) { ulStatus = pdFAIL; } /* There should always be one item in the queue. */ if( uxQueueMessagesWaiting( xTaskQueue ) != uxQueueLength ) { ulStatus = pdFAIL; } } /* Empty the queue again. */ xQueueReceive( xTaskQueue, &ulValue, qoDONT_BLOCK ); if( uxQueueMessagesWaiting( xTaskQueue ) != 0 ) { ulStatus = pdFAIL; } if( ulStatus != pdFAIL ) { /* Increment a counter to show this task is still running without error. */ ulLoopCounter++; } #if( configUSE_PREEMPTION == 0 ) taskYIELD(); #endif } }
void vUSBTask( void *pvParameters ) { int c; /* Just to prevent compiler warnings about the unused parameter. */ ( void ) pvParameters; DBG("Initialising USB stack\n"); xRxedChars = xQueueCreate( usbBUFFER_LEN, sizeof( char ) ); xCharsForTx = xQueueCreate( usbBUFFER_LEN, sizeof( char ) ); if( ( xRxedChars == NULL ) || ( xCharsForTx == NULL ) ) { /* Not enough heap available to create the buffer queues, can't do anything so just delete ourselves. */ vTaskDelete( NULL ); } // initialise stack USBInit(); // register descriptors USBRegisterDescriptors(abDescriptors); // register class request handler USBRegisterRequestHandler(REQTYPE_TYPE_CLASS, HandleClassRequest, abClassReqData); // register endpoint handlers USBHwRegisterEPIntHandler(INT_IN_EP, NULL); USBHwRegisterEPIntHandler(BULK_IN_EP, BulkIn); USBHwRegisterEPIntHandler(BULK_OUT_EP, BulkOut); // register frame handler USBHwRegisterFrameHandler(USBFrameHandler); // enable bulk-in interrupts on NAKs USBHwNakIntEnable(INACK_BI); DBG("Starting USB communication\n"); NVIC_SetPriority( USB_IRQn, configUSB_INTERRUPT_PRIORITY ); NVIC_EnableIRQ( USB_IRQn ); // connect to bus DBG("Connecting to USB bus\n"); USBHwConnect(TRUE); // echo any character received (do USB stuff in interrupt) for( ;; ) { c = VCOM_getchar(); if (c != EOF) { // Echo character back with INCREMENT_ECHO_BY offset, so for example if // INCREMENT_ECHO_BY is 1 and 'A' is received, 'B' will be echoed back. VCOM_putchar(c + INCREMENT_ECHO_BY ); } } }
void AudioTask ( void * pvParameters ) { struct AAudioCommandMessage CmdMsg; uint8_t rc = 0; FRESULT res; uint8_t pausing = 0; xAudioQueue = xQueueCreate ( 8, sizeof ( char ) ); res = f_mount ( &FatFs, "", 1 ); // mount the drive if ( res ) { led_state[0] = LED_STATE_BLINK_FAST; while ( 1 ); } while ( 1 ) { if ( xQueueReceive ( xAudioQueue, &CmdMsg, portMAX_DELAY ) ) { switch ( CmdMsg.Command ) { case 'h': // half transfer complete break; case 't': // transfer complete if ( audioContext.lastFrame ) { EVAL_AUDIO_Stop ( CODEC_PDWN_SW ); } else { AudioProvideSamplesFromFile ( ); } break; case 'p': // play file rc = AudioStartPlayFile ( CmdMsg.sFilename ); switch ( rc ) { case 0: led_state[1] = LED_STATE_OFF; led_state[2] = LED_STATE_OFF; break; case 1: led_state[1] = LED_STATE_BLINK_FAST; break; case 2: led_state[2] = LED_STATE_BLINK_FAST; break; } break; case 'r': // pause/resume EVAL_AUDIO_PauseResume ( pausing ? AUDIO_RESUME : AUDIO_PAUSE ); pausing ^= pausing; break; case 's': // stop playback EVAL_AUDIO_Stop ( CODEC_PDWN_SW ); break; case 'v': // set volume break; case '+': // volume up break; case '-': // volume down break; case 'n': // next file break; case 'l': // last file break; }; }; }; };
int main(void) { /* Configure the NVIC, LED outputs and button inputs. */ prvSetupHardware(); /* Create the queue. */ xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( unsigned long ) ); if( xQueue != NULL ) { /* Start the three application specific demo tasks, as described in the comments at the top of this file. */ xTaskCreate( prvQueueReceiveTask, "Rx", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_RECEIVE_TASK_PRIORITY, NULL ); xTaskCreate( prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL ); xTaskCreate( prvOLEDTask, "OLED", configMINIMAL_STACK_SIZE, NULL, mainOLED_TASK_PRIORITY, NULL ); /* Create the software timer that is responsible for turning off the LED if the button is not pushed within 5000ms, as described at the top of this file. */ xLEDTimer = xTimerCreate( "LEDTimer", /* A text name, purely to help debugging. */ ( mainLED_TIMER_PERIOD_MS ), /* The timer period, in this case 5000ms (5s). */ pdFALSE, /* This is a one shot timer, so xAutoReload is set to pdFALSE. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */ prvLEDTimerCallback /* The callback function that switches the LED off. */ ); /* Create the software timer that performs the 'check' functionality, as described at the top of this file. */ xCheckTimer = xTimerCreate( "CheckTimer", /* A text name, purely to help debugging. */ ( mainCHECK_TIMER_PERIOD_MS ), /* The timer period, in this case 3000ms (3s). */ pdTRUE, /* This is an auto-reload timer, so xAutoReload is set to pdTRUE. */ ( void * ) 0, /* The ID is not used, so can be set to anything. */ prvCheckTimerCallback /* The callback function that inspects the status of all the other tasks. */ ); /* Create a lot of 'standard demo' tasks. */ vStartBlockingQueueTasks( mainBLOCK_Q_PRIORITY ); vCreateBlockTimeTasks(); vStartSemaphoreTasks( mainSEM_TEST_PRIORITY ); vStartGenericQueueTasks( mainGEN_QUEUE_TASK_PRIORITY ); vStartLEDFlashTasks( mainFLASH_TASK_PRIORITY ); vStartQueuePeekTasks(); vStartRecursiveMutexTasks(); vStartTimerDemoTask( mainTIMER_TEST_PERIOD ); /* Create the web server task. */ xTaskCreate( vuIP_Task, "uIP", mainuIP_STACK_SIZE, NULL, mainuIP_TASK_PRIORITY, NULL ); /* The suicide tasks must be created last, as they need to know how many tasks were running prior to their creation in order to ascertain whether or not the correct/expected number of tasks are running at any given time. */ vCreateSuicidalTasks( mainCREATOR_TASK_PRIORITY ); /* Start the tasks and timer running. */ vTaskStartScheduler(); } /* If all is well, the scheduler will now be running, and the following line will never be reached. If the following line does execute, then there was insufficient FreeRTOS heap memory available for the idle and/or timer tasks to be created. See the memory management section on the FreeRTOS web site for more details. */ for( ;; ); }
static void prvSetupTest( void ) { portBASE_TYPE x; unsigned long ulValueToSend = 0; /* Ensure the queues are created and the queue set configured before the sending task is unsuspended. First Create the queue set such that it will be able to hold a message for every space in every queue in the set. */ xQueueSet = xQueueCreateSet( queuesetNUM_QUEUES_IN_SET * queuesetQUEUE_LENGTH ); for( x = 0; x < queuesetNUM_QUEUES_IN_SET; x++ ) { /* Create the queue and add it to the set. The queue is just holding unsigned long value. */ xQueues[ x ] = xQueueCreate( queuesetQUEUE_LENGTH, sizeof( unsigned long ) ); configASSERT( xQueues[ x ] ); if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdPASS ) { xQueueSetTasksStatus = pdFAIL; } else { /* The queue has now been added to the queue set and cannot be added to another. */ if( xQueueAddToSet( xQueues[ x ], xQueueSet ) != pdFAIL ) { xQueueSetTasksStatus = pdFAIL; } } } /* Attempt to remove a queue from a queue set it does not belong to (NULL being passed as the queue set in this case). */ if( xQueueRemoveFromSet( xQueues[ 0 ], NULL ) != pdFAIL ) { /* It is not possible to successfully remove a queue from a queue set it does not belong to. */ xQueueSetTasksStatus = pdFAIL; } /* Attempt to remove a queue from the queue set it does belong to. */ if( xQueueRemoveFromSet( xQueues[ 0 ], xQueueSet ) != pdPASS ) { /* It should be possible to remove the queue from the queue set it does belong to. */ xQueueSetTasksStatus = pdFAIL; } /* Add an item to the queue before attempting to add it back into the set. */ xQueueSend( xQueues[ 0 ], ( void * ) &ulValueToSend, 0 ); if( xQueueAddToSet( xQueues[ 0 ], xQueueSet ) != pdFAIL ) { /* Should not be able to add a non-empty queue to a set. */ xQueueSetTasksStatus = pdFAIL; } /* Remove the item from the queue before adding the queue back into the set so the dynamic tests can begin. */ xQueueReceive( xQueues[ 0 ], &ulValueToSend, 0 ); if( xQueueAddToSet( xQueues[ 0 ], xQueueSet ) != pdPASS ) { /* If the queue was successfully removed from the queue set then it should be possible to add it back in again. */ xQueueSetTasksStatus = pdFAIL; } /* The task that sends to the queues is not running yet, so attempting to read from the queue set should fail. */ if( xQueueSelectFromSet( xQueueSet, queuesetSHORT_DELAY ) != NULL ) { xQueueSetTasksStatus = pdFAIL; } /* Resume the task that writes to the queues. */ vTaskResume( xQueueSetSendingTask ); /* Let the ISR access the queues also. */ xSetupComplete = pdTRUE; }
void prvTCPCpmIOTask( void *ram ) { BaseType_t iosize; char cRxedChar, cInputIndex = 0; struct freertos_sockaddr xClient; Socket_t xListeningSocket; socklen_t xSize = sizeof( xClient ); cpminq = xQueueCreate(81, sizeof( CHAR)); while(FreeRTOS_IsNetworkUp() == pdFALSE) vTaskDelay(3000); /* Create the socket. */ xSocketRDisk = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP ); /* Check the socket was created. */ configASSERT( xSocketRDisk != FREERTOS_INVALID_SOCKET ); for( ;; ) { /* Attempt to open the socket. The port number is passed in the task parameter. The strange casting is to remove compiler warnings on 32-bit machines. NOTE: The FREERTOS_SO_REUSE_LISTEN_SOCKET option is used, so the listening and connecting socket are the same - meaning only one connection will be accepted at a time, and that xListeningSocket must be created on each iteration. */ xListeningSocket = prvOpenTCPServerSocket( RDSK_PORT); /* Nothing for this task to do if the socket cannot be created. */ if( xListeningSocket == FREERTOS_INVALID_SOCKET ) { vTaskDelete( NULL ); } /* Wait for an incoming connection. */ xConnectedSocket = FreeRTOS_accept( xListeningSocket, &xClient, &xSize ); /* The FREERTOS_SO_REUSE_LISTEN_SOCKET option is set, so the connected and listening socket should be the same socket. */ configASSERT( xConnectedSocket == xListeningSocket ); xRDiskAddress.sin_addr = xClient.sin_addr; xRDiskAddress.sin_port = FreeRTOS_htons( RDSK_PORT ); iosize = xTaskCreate( CPM22Task, "CPM22Task", configMINIMAL_STACK_SIZE*5, ram, PRIO_CPM22,&thcpm); if(iosize != pdPASS) { prvGracefulShutdown( xListeningSocket ); vTaskDelete( NULL ); } /* Send the welcome message. */ iosize = FreeRTOS_send( xConnectedSocket, ( void * ) pcWelcomeMessage, strlen( pcWelcomeMessage ), 0 ); xQueueReset(cpminq); /* Process the socket as long as it remains connected. */ while( iosize >= 0 ) { char c; /* Receive data on the socket. */ iosize = FreeRTOS_recv( xConnectedSocket, &c, 1, 0 ); if( iosize >= 0 ) { xQueueSend(cpminq,&c,0); } else { /* Socket closed? */ break; } } /* Close the socket correctly. */ prvGracefulShutdown( xListeningSocket ); } }
static void prvTestAbortingQueueSend( void ) { TickType_t xTimeAtStart; BaseType_t xReturn; const UBaseType_t xQueueLength = ( UBaseType_t ) 1; QueueHandle_t xQueue; uint8_t ucItemToQueue; #if( configSUPPORT_STATIC_ALLOCATION == 1 ) { static StaticQueue_t xQueueBuffer; static uint8_t ucQueueStorage[ sizeof( uint8_t ) ]; /* Create the queue. Statically allocated memory is used so the creation cannot fail. */ xQueue = xQueueCreateStatic( xQueueLength, sizeof( uint8_t ), ucQueueStorage, &xQueueBuffer ); } #else { xQueue = xQueueCreate( xQueueLength, sizeof( uint8_t ) ); configASSERT( xQueue ); } #endif /* This function tests aborting when in the blocked state waiting to send, so the queue must be full. There is only one space in the queue. */ xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime ); if( xReturn != pdPASS ) { xErrorOccurred = pdTRUE; } /* Note the time before the delay so the length of the delay is known. */ xTimeAtStart = xTaskGetTickCount(); /* This first delay should just time out. */ xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime ); if( xReturn != pdFALSE ) { xErrorOccurred = pdTRUE; } prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); /* Note the time before the delay so the length of the delay is known. */ xTimeAtStart = xTaskGetTickCount(); /* This second delay should be aborted by the primary task half way through. */ xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime ); if( xReturn != pdFALSE ) { xErrorOccurred = pdTRUE; } prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xHalfMaxBlockTime ); /* Note the time before the delay so the length of the delay is known. */ xTimeAtStart = xTaskGetTickCount(); /* This third delay should just time out again. */ xReturn = xQueueSend( xQueue, &ucItemToQueue, xMaxBlockTime ); if( xReturn != pdFALSE ) { xErrorOccurred = pdTRUE; } prvCheckExpectedTimeIsWithinAnAcceptableMargin( xTimeAtStart, xMaxBlockTime ); /* Not really necessary in this case, but for completeness. */ vQueueDelete( xQueue ); }