I want to receive data from 2 sensors connected to my STM32F4-Discovery via 2 UARTs. Transmitting data from STM32 to sensors works but receiving doesn´t. Guarantee it isn´t a hardware problem. I found tutorials for 1 connected UART but not for 2 at once. I would like to use new HAL drivers and DMA for receiving. Thanks for help.
UART_HandleTypeDef huart4;
UART_HandleTypeDef huart5;
DMA_HandleTypeDef hdma_uart4_rx;
DMA_HandleTypeDef hdma_uart5_rx;
uint8_t rxBuffer4 = '\000';
uint8_t rxBuffer5 = '\000';
void initGPIOs_UART4(void){
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_11;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_MEDIUM;
GPIO_InitStructure.Alternate = GPIO_AF8_UART4;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
}
void initGPIOs_UART5(void){
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = GPIO_PIN_12;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_MEDIUM;
GPIO_InitStructure.Alternate = GPIO_AF8_UART5;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
GPIO_InitStructure.Pin = GPIO_PIN_2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
}
void initUART4(void){
initGPIOs_UART4();
__HAL_RCC_UART4_CLK_ENABLE();
huart4.Instance = UART4;
huart4.Init.BaudRate = 9600;
huart4.Init.WordLength = UART_WORDLENGTH_8B;
huart4.Init.StopBits = UART_STOPBITS_1;
huart4.Init.Parity = UART_PARITY_NONE;
huart4.Init.Mode = UART_MODE_TX_RX;
huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart4.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart4);
__HAL_UART_FLUSH_DRREGISTER(&huart4);
}
void initUART5(void){
initGPIOs_UART5();
__HAL_RCC_UART5_CLK_ENABLE();
huart5.Instance = UART5;
huart5.Init.BaudRate = 9600;
huart5.Init.WordLength = UART_WORDLENGTH_8B;
huart5.Init.StopBits = UART_STOPBITS_1;
huart5.Init.Parity = UART_PARITY_NONE;
huart5.Init.Mode = UART_MODE_TX_RX;
huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart5.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&huart5);
__HAL_UART_FLUSH_DRREGISTER(&huart5);
}
void receive_start_UART4(void){
HAL_UART_Receive_DMA(&huart4, &rxBuffer4, 1);
}
void receive_start_UART5(void){
HAL_UART_Receive_DMA(&huart5, &rxBuffer5, 1);
}
void print_UART4(uint8_t string[], uint8_t length){
HAL_UART_Transmit(&huart4, (uint8_t*)string, length, 5);
}
void print_UART5(uint8_t string[], uint8_t length){
HAL_UART_Transmit(&huart5, (uint8_t*)string, length, 5);
}
void initDMA1_UART4(void){
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_uart4_rx.Instance = DMA1_Stream2;
hdma_uart4_rx.Init.Channel = DMA_CHANNEL_4;
hdma_uart4_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart4_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart4_rx.Init.MemInc = DMA_MINC_DISABLE;
hdma_uart4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart4_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart4_rx.Init.Mode = DMA_CIRCULAR;
hdma_uart4_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_uart4_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_uart4_rx);
__HAL_LINKDMA(&huart4, hdmarx, hdma_uart4_rx);
HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
}
void initDMA1_UART5(void){
__HAL_RCC_DMA1_CLK_ENABLE();
hdma_uart5_rx.Instance = DMA1_Stream1;
hdma_uart5_rx.Init.Channel = DMA_CHANNEL_5;
hdma_uart5_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_uart5_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_uart5_rx.Init.MemInc = DMA_MINC_DISABLE;
hdma_uart5_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_uart5_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_uart5_rx.Init.Mode = DMA_CIRCULAR;
hdma_uart5_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_uart5_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_uart5_rx);
__HAL_LINKDMA(&huart5, hdmarx, hdma_uart5_rx);
HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
}
void DMA1_Stream2_IRQHandler(void){
HAL_NVIC_ClearPendingIRQ(DMA1_Stream2_IRQn);
HAL_DMA_IRQHandler(&hdma_uart4_rx);
}
void DMA1_Stream1_IRQHandler(void){
HAL_NVIC_ClearPendingIRQ(DMA1_Stream1_IRQn);
HAL_DMA_IRQHandler(&hdma_uart5_rx);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
__HAL_UART_FLUSH_DRREGISTER(&huart4);
__HAL_UART_FLUSH_DRREGISTER(&huart5);
trace_printf("%d - %d\n",rxBuffer4,rxBuffer5);
//Here I´m able to receive only from UART4
}
Wrong DMA Stream/Channel
DMA1_Stream1 DMA_CHANNEL_5 is assigned to UART7_TX.
The stream/channel for UART5_RX should be DMA1_Stream0 DMA_CHANNEL_4.
See Reference Manual RM0090
page 308
Related
I am trying to convert an CVPixelBuffer format from YUV('2vuy') to ARGB using Accelerate framework with the below code.
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
void* baseAddress = CVPixelBufferGetBaseAddress(pixelBuffer);
size_t srcBufferWidth = CVPixelBufferGetWidth(pixelBuffer);
size_t srcBufferHeight = CVPixelBufferGetHeight(pixelBuffer);
size_t srcBufferBytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer);
vImage_Error err = kvImageNoError;
static vImage_YpCbCrToARGB outInfo;
static bool infoGenerated = false;
if (!infoGenerated) {
vImage_YpCbCrPixelRange pixelRange;
pixelRange.Yp_bias = 16;
pixelRange.CbCr_bias = 128;
pixelRange.YpRangeMax = 235;
pixelRange.CbCrRangeMax = 240;
pixelRange.YpMax = 255;
pixelRange.YpMin = 0;
pixelRange.CbCrMax = 255;
pixelRange.CbCrMin = 1;
const vImage_YpCbCrToARGBMatrix *matrixYpCbCrToARGB = kvImage_YpCbCrToARGBMatrix_ITU_R_709_2;
err = vImageConvert_YpCbCrToARGB_GenerateConversion(matrixYpCbCrToARGB, &pixelRange, &outInfo, kvImage422CbYpCrYp8, kvImageARGB8888, kvImageNoFlags);
if (err ==kvImageNoError) {
infoGenerated = true;
}
}
if (infoGenerated) {
const uint8_t permuteMap[4] = {0, 1, 2, 3};
vImage_Buffer srcBuffer = { (void *)baseAddress, srcBufferHeight, srcBufferWidth, srcBufferBytesPerRow};
void *destData = malloc(srcBufferWidth * srcBufferHeight * 4);
vImage_Buffer destBuffer = {
.data = destData,
.width = srcBufferWidth,
.height = srcBufferHeight,
.rowBytes = srcBufferWidth * 4
};
err = vImageConvert_422CbYpCrYp8ToARGB8888(&srcBuffer, &destBuffer, &outInfo, permuteMap, 0, kvImageNoFlags);
if (err!=kvImageNoError) {
NSLog(#"vImage_Error converting vImageConvert_422CbYpCrYp8ToARGB8888 errorcode:%ld",err);
}
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
}
The conversion is successful but the resulting destination buffer has a blue shade. I want it in the original colour. What Am I missing or doing wrong here?
Source buffer:
Destination Buffer:
STM32F4329II Input capture Interrupt is ignored while trying to use the input capture
static void TIM_Config(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //GPIO_PuPd_NOPULL;
GPIO_PinAFConfig(GPIOH, GPIO_PinSource11, GPIO_AF_TIM5);
GPIO_Init(GPIOH, &GPIO_InitStructure);
/* TIM5 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
TIM_ICInitTypeDef TIM_InputCaptureInitStructure;
TIM_InputCaptureInitStructure.TIM_Channel = TIM_Channel_2;
TIM_InputCaptureInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_InputCaptureInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_InputCaptureInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_InputCaptureInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM5, &TIM_InputCaptureInitStructure);
TIM_ClearFlag(TIM5, TIM_FLAG_CC2 );
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //
NVIC_Init(&NVIC_InitStructure);
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
//Enable CC2 interrupt
TIM_ITConfig(TIM5,TIM_IT_CC2,ENABLE);
//EnableTIM5
TIM_Cmd(TIM5,ENABLE);
}
And the following IRQ
extern "C" void TIM5_IRQHandler(void)
{
if (TIM_GetITStatus(TIM5, TIM_IT_CC2) == SET)
{
TIM_ClearITPendingBit(TIM5, TIM_IT_CC2);
rpm4 = TIM_GetCapture2(TIM5);
static char xx[12];
sprintf( xx, " %l", rpm4 );
GUI_DispStringAt(xx,100,150);
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC2 );
}
I put some breakpoints inside the Interrupt routine but nothing happens...
My external signal is a 5V signal ( this micro is 5V tolerant... ) with negative pulses...
#include <stm32f4xx.h>
#include "stm32f4xx_spi.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "config.h"
void init_GPIO()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOI,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOI , &GPIO_InitStructure);
}
void SPI1_Configuration_master(void)
{
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(Open_SPI1_SCK_GPIO_CLK | Open_SPI1_MISO_GPIO_CLK | Open_SPI1_MOSI_GPIO_CLK |Open_SPI1_NSS_GPIO_CLK ,ENABLE);
RCC_APB2PeriphClockCmd(Open_RCC_APB2Periph_SPI1,ENABLE);
GPIO_PinAFConfig(Open_SPI1_SCK_GPIO_PORT, Open_SPI1_SCK_SOURCE, Open_SPI1_MOSI_AF);
GPIO_PinAFConfig(Open_SPI1_MISO_GPIO_PORT, Open_SPI1_MISO_SOURCE, Open_SPI1_MOSI_AF);
GPIO_PinAFConfig(Open_SPI1_MOSI_GPIO_PORT, Open_SPI1_MOSI_SOURCE, Open_SPI1_MOSI_AF);
GPIO_PinAFConfig(Open_SPI1_NSS_GPIO_PORT, Open_SPI1_NSS_SOURCE, Open_SPI1_NSS_AF);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_SCK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(Open_SPI1_SCK_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_MISO_PIN;
GPIO_Init(Open_SPI1_MISO_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_MOSI_PIN;
GPIO_Init(Open_SPI1_MOSI_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_NSS_PIN;
GPIO_Init(Open_SPI1_NSS_GPIO_PORT, &GPIO_InitStructure);
SPI_I2S_DeInit(Open_SPI1);
SPI_InitStruct.SPI_Direction= SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft ;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_CRCPolynomial = 7;
SPI_Init(Open_SPI1, &SPI_InitStruct);
SPI_Cmd(Open_SPI1, ENABLE);
}
void SPI_Configuration2_slave(void)
{
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(Open_SPI2_SCK_GPIO_CLK | Open_SPI2_MISO_GPIO_CLK | Open_SPI2_MOSI_GPIO_CLK| Open_SPI2_NSS_GPIO_CLK,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
GPIO_PinAFConfig(Open_SPI2_SCK_GPIO_PORT, Open_SPI2_SCK_SOURCE, Open_SPI2_MOSI_AF);
GPIO_PinAFConfig(Open_SPI2_MISO_GPIO_PORT, Open_SPI2_MISO_SOURCE, Open_SPI2_MOSI_AF);
GPIO_PinAFConfig(Open_SPI2_MOSI_GPIO_PORT, Open_SPI2_MOSI_SOURCE, Open_SPI2_MOSI_AF);
GPIO_PinAFConfig(Open_SPI2_MOSI_GPIO_PORT, Open_SPI2_NSS_SOURCE, Open_SPI2_MOSI_AF);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_SCK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(Open_SPI2_SCK_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_MISO_PIN;
GPIO_Init(Open_SPI2_MISO_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_MOSI_PIN;
GPIO_Init(Open_SPI2_MOSI_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_NSS_PIN;
GPIO_Init(Open_SPI2_MOSI_GPIO_PORT, &GPIO_InitStructure);
SPI_I2S_DeInit(Open_SPI2);
SPI_InitStruct.SPI_Direction= SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_Mode = SPI_Mode_Slave;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft ;
//SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_CRCPolynomial = 7;
SPI_Init(Open_SPI2, &SPI_InitStruct);
SPI_Cmd(Open_SPI2, ENABLE);
}
u16 SPI2_Send_byte(u16 data)
{
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI2,data);
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open_SPI2);
}
u16 SPI2_Receive_byte(void)
{/*
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI2,0x00);
*/
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open_SPI2);
}
u16 SPI_Send_byte(u16 data)
{
GPIO_ResetBits(GPIOI,GPIO_Pin_10);
while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI1,data);
while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_RXNE)==RESET);
GPIO_SetBits(GPIOI,GPIO_Pin_10);
return SPI_I2S_ReceiveData(Open_SPI1);
}
u16 SPI_Receive_byte(u16 data)
{
/*while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI1,data);
*/
while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open_SPI1);
}
int main()
{
char a;
init_GPIO();
SPI_Configuration2_slave();
SPI1_Configuration_master();
GPIO_SetBits(GPIOI,GPIO_Pin_10);
while(1)
{
a =SPI_Send_byte((u16)'a');
a = SPI2_Receive_byte();
}
return 0;
}
I am trying to implement Spi on STM32F407ig
I am currently trying to implement communication between two Spi1 and SPI2 on the same board.
I tried the similar code for communication between boards.
when i loop back mosi and miso of master i get the data transmitted.
but the slave does not receive any thing or it receives zero.
The connections made are right.
also the Macros used like Open_SPI1 are right.
I want to know if my configuration of SPI master and slave is right.
Could someone also elaborate on how the NSS software exactly work.
I had an issue with SPI on STM32F2 series. I had to toggle the NSS line manually and everything worked fine after that. Not sure if F4 has the same problem (maybe it's even by design). Here's my code:
/******************************************************************************/
void SPI_GPIO_init( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure SPI pins SCK and MOSI to be hardware controlled */
GPIO_InitStructure.GPIO_Pin = SPI_PIN_SCK | SPI_PIN_MOSI;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( SPI_GPIO_PORT, &GPIO_InitStructure );
/* Configure SPI pin MISO to be an input pin since we are master */
GPIO_InitStructure.GPIO_Pin = SPI_PIN_MISO;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( SPI_GPIO_PORT, &GPIO_InitStructure );
/* Configure SPI pin NSS to be a regular GPIO output. This is due to STM32
* goofy handling of SPI: NSS stays low for the entire duration of SPI being
* enabled instead of being released after outgoing data is completed. This
* is basically a HW bug but it definitely mentiones this in the Ref Manual.
*
* From the reference manual RM0090:
* - NSS output enabled (SSM = 0, SSOE = 1)
* This configuration is used only when the device operates in master mode.
* The NSS signal is driven low when the master starts the communication and
* is kept low until the SPI is disabled.
*
* Instead, we are going to drive this pin manually as CLRC663 chip expects
* */
GPIO_InitStructure.GPIO_Pin = SPI_PIN_NSS;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( SPI_GPIO_PORT, &GPIO_InitStructure );
SPI_NSS_high();
DelayMS(1);
}
/******************************************************************************/
void SPI_NSS_high( void )
{
GPIO_WriteBit( SPI_GPIO_PORT, SPI_PIN_NSS, Bit_SET);
}
/******************************************************************************/
void SPI_NSS_low( void )
{
GPIO_WriteBit( SPI_GPIO_PORT, SPI_PIN_NSS, Bit_RESET);
}
/******************************************************************************/
void SPI_init( void )
{
SPI_I2S_DeInit( SPI1 );
SPI_NSS_high();
SPI_InitTypeDef SPI_InitStructure;
/* SPI1 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 0;
SPI_Init( SPI1, &SPI_InitStructure );
SPI_Cmd( SPI1, ENABLE );
/* Not using interrupts for SPI communication so don't enable the NVIC and
* the ISR for it.*/
}
/******************************************************************************/
Error SPI_send( uint8_t *snd_buf, uint8_t snd_buf_len )
{
uint8_t snd_indx = 0;
uint8_t spi_retry = 0;
SPI_NSS_low(); /* Assert the NSS pin low to become SPI bus master */
for ( snd_indx = 0; snd_indx < snd_buf_len; snd_indx++ )
{
/* When SPI Tx buffer is empty, send data. Make sure we don't get
* stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to send data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
SPI_I2S_SendData( SPI1, snd_buf[ snd_indx ] );
// debug_printf("Sent %02x\n", snd_buf[ snd_indx ]);
/* Get the dummy byte coming back when SPI Rx buffer is empty. Make sure
* we don't get stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_RXNE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to receive data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
SPI_I2S_ReceiveData( SPI1 ); /* Dummy byte so no need to store it */
}
SPI_NSS_high(); /* Assert the NSS pin high to release SPI bus master */
return ( ERR_NONE );
}
/******************************************************************************/
Error SPI_transceive(
uint8_t *snd_buf,
uint8_t snd_buf_len,
uint8_t *rcv_buf,
uint8_t rcv_buf_len
)
{
uint8_t snd_indx = 0;
uint8_t rcv_indx = 0;
uint16_t spi_retry = 0;
SPI_NSS_low(); /* Assert the NSS pin low to become SPI bus master */
if ( snd_buf_len != rcv_buf_len )
{
err_printf("SPI expects to receive same amount of data that it is sending\n");
return ( ERR_HW_SPI_LENGTH_MISMATCH );
}
for ( snd_indx = 0; snd_indx < snd_buf_len; snd_indx++, rcv_indx++ )
{
/* When SPI Tx buffer is empty, send data. Make sure we don't get
* stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to send data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
SPI_I2S_SendData( SPI1, snd_buf[ snd_indx ] );
/* Now receive the reply when the Rx buffer is empty. Make sure we don't
* get stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_RXNE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to receive data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
uint8_t data = SPI_I2S_ReceiveData( SPI1 );
rcv_buf[ rcv_indx ] = data;
// debug_printf("Got %02x\n", data );
}
SPI_NSS_high(); /* Assert the NSS pin high to release SPI bus master */
return ( ERR_NONE );
}
I am using X264 and librtmp to send my live camera frame, all the things seems right. but my web test flash can't show the correct video. Sometimes it seems correct, but when I re-click play button, it doesn't show any picture on the flash.
Here is my X264 config code
x264_param_default_preset(&x264param, "ultrafast", "zerolatency");
x264param.i_threads = 2;
x264param.i_width = width;
x264param.i_height = height;
x264param.i_log_level = X264_LOG_DEBUG;
x264param.i_fps_num = x264param.i_timebase_num= fps;
x264param.i_fps_den = x264param.i_timebase_den=1;
x264param.i_frame_total = 0;
x264param.i_frame_reference =1;
//x264param.i_frame_reference = 2;
x264param.i_keyint_min = 25;
x264param.i_keyint_max = fps*3;
x264param.i_scenecut_threshold = 40;
x264param.b_deblocking_filter = 1;
x264param.b_cabac = 0;
x264param.analyse.i_trellis = 0;
x264param.analyse.b_chroma_me = 1;
x264param.vui.i_sar_width = 0;
x264param.vui.i_sar_height = 0;
x264param.i_bframe_bias = 0;
x264param.b_interlaced= 0;
x264param.analyse.i_subpel_refine = 6; /* 0..5 -> 1..6 */
x264param.analyse.i_me_method = X264_ME_DIA;//X264_ME_HEX?X264_ME_DIA
x264param.analyse.i_me_range = 16;
x264param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
x264param.i_deblocking_filter_alphac0 = 0;
x264param.i_deblocking_filter_beta = 0;
//x264param.analyse.intra = X264_ANALYSE_I4x4;
x264param.analyse.intra = X264_ANALYSE_I4x4;// | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16;
x264param.analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16;
//edit 2014-7-28
x264param.analyse.b_transform_8x8 = 1;
//x264param.analyse.b_transform_8x8 = 0;
x264param.analyse.b_fast_pskip = 1;
x264param.i_bframe = 0;
//x264param.b_intra_refresh
x264param.analyse.b_weighted_bipred = 0;
//// Intra refres:
x264param.i_keyint_max = 250;
x264param.b_intra_refresh = 0;
////Rate control:
//x264param.rc.i_rc_method = X264_RC_CRF;
//Rate Control
x264param.rc.f_ip_factor = 1.4f;
x264param.rc.f_pb_factor = 1.3f;
x264param.rc.f_qcompress = 1.0;
x264param.rc.i_qp_min = 20;//20;
x264param.rc.i_qp_max = 32;
x264param.rc.i_qp_step = 1;
switch (0)
{
case 0: /* 1 PASS ABR */
x264param.rc.i_rc_method = X264_RC_ABR;
x264param.rc.i_bitrate = 300; // max = 5000
x264param.rc.b_mb_tree = 0;
break;
case 1: /* 1 PASS CQ */
x264param.rc.i_rc_method = X264_RC_CQP;
x264param.rc.i_qp_constant = 26;//10 - 51
break;
}
//For streaming:
x264param.b_repeat_headers = 1;
x264param.b_annexb = 1;
x264_param_apply_profile(&x264param, "baseline");
encoder = x264_encoder_open(&x264param);
x264_picture_init( &pic_in );
x264_picture_alloc(&pic_in, X264_CSP_I420, width, height);
pic_in.img.i_csp = X264_CSP_I420|X264_CSP_VFLIP;
pic_in.img.i_plane = 3;
pic_in.i_type = X264_TYPE_AUTO;
Sending To RTMP:
sws_scale(convertCtx,&a,&scribe,0,height, pic_in.img.plane, pic_in.img.i_stride);
int i_nal;
int i_frame_size = x264_encoder_encode( encoder, &nal, &i_nal, &pic_in, &pic_out );
if(i_frame_size <= 0){
printf("\t!!!FAILED encode frame \n");
}else{
for (int i = 0,last=0; i < i_nal;i++)
{
fwrite(nal[i].p_payload, 1, i_frame_size-last, fpw1);
if (nal[i].i_type == NAL_SPS) {
sps_len = nal[i].i_payload-4;
sps = new unsigned char[sps_len];
memcpy(sps,nal[i].p_payload+4,sps_len);
} else if (nal[i].i_type == NAL_PPS) {
pps_len = nal[i].i_payload-4;
pps = new unsigned char[sps_len];
memcpy(pps,nal[i].p_payload+4,pps_len);
send_video_sps_pps();
free(sps);
free(pps);
} else {
send_rtmp_video(nal[i].p_payload,i_frame_size-last);
break;
}
last += nal[i].i_payload;
}
}
Send PPS and SPS
void send_video_sps_pps(){
if(rtmp!= NULL){
RTMPPacket * packet;
unsigned char * body;
int i;
packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE+1024);
memset(packet,0,RTMP_HEAD_SIZE);
packet->m_body = (char *)packet + RTMP_HEAD_SIZE;
body = (unsigned char *)packet->m_body;
i = 0;
body[i++] = 0x17;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
/*AVCDecoderConfigurationRecord*/
body[i++] = 0x01;
body[i++] = sps[1];
body[i++] = sps[2];
body[i++] = sps[3];
body[i++] = 0xff;
/*sps*/
body[i++] = 0xe1;
body[i++] = (sps_len >> 8) & 0xff;
body[i++] = sps_len & 0xff;
memcpy(&body[i],sps,sps_len);
i += sps_len;
/*pps*/
body[i++] = 0x01;
body[i++] = (pps_len >> 8) & 0xff;
body[i++] = (pps_len) & 0xff;
memcpy(&body[i],pps,pps_len);
i += pps_len;
packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;
packet->m_nBodySize = i;
packet->m_nChannel = 0x04;
packet->m_nTimeStamp = 0;
packet->m_hasAbsTimestamp = 0;
packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM;
packet->m_nInfoField2 = rtmp->m_stream_id;
RTMP_SendPacket(rtmp,packet,TRUE);
free(packet);
rtmp_start_time = GetTickCount();
}else{
std::cout<<"RTMP is not ready"<<std::endl;
}
}
Send video Frame
void send_rtmp_video(unsigned char * buf,int len){
RTMPPacket * packet;
long timeoffset = GetTickCount() - rtmp_start_time;
int type = buf[0]&0x1f;
packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE+len+9);
memset(packet,0,RTMP_HEAD_SIZE);
packet->m_body = (char *)packet + RTMP_HEAD_SIZE;
packet->m_nBodySize = len + 9;
/*send video packet*/
unsigned char *body = (unsigned char *)packet->m_body;
memset(body,0,len+9);
/*key frame*/
body[0] = 0x27;
if (type == NAL_SLICE_IDR) {
body[0] = 0x17;
}
body[1] = 0x01; /*nal unit*/
body[2] = 0x00;
body[3] = 0x00;
body[4] = 0x00;
body[5] = (len >> 24) & 0xff;
body[6] = (len >> 16) & 0xff;
body[7] = (len >> 8) & 0xff;
body[8] = (len ) & 0xff;
/*copy data*/
memcpy(&body[9],buf,len);
packet->m_hasAbsTimestamp = 0;
packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;
if(rtmp != NULL){
packet->m_nInfoField2 = rtmp->m_stream_id;
}
packet->m_nChannel = 0x04;
packet->m_headerType = RTMP_PACKET_SIZE_LARGE;
packet->m_nTimeStamp = timeoffset;
if(rtmp != NULL){
RTMP_SendPacket(rtmp,packet,TRUE);
}
free(packet);
}
Try changing:
pps = new unsigned char[sps_len];
to:
pps = new unsigned char[pps_len];
I'm using the STM32F373 microcontroller and wrote a simple function to read data from a MPU6050 gyro+accel on i2c 1 (PB7 PB6).
The problem is that when I try to read sensor register data - flag I2C_ISR_TXIS is always equal to RESET (not set).
Why might this happen?
Here is some source code that demonstrates the problem.
void i2c1_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_4);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_Timing = 0xC062121F;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
uint8_t i2c_read(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t* pBuffer, uint16_t len)
{
/* Test on BUSY Flag */
uint32_t timeout = I2C_TIMEOUT;
while(I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET)
{
if((timeout--) == 0) return 0;
}
I2C_TransferHandling(I2C1, DeviceAddr, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
/* !!! Wait until TXIS flag is set !!! */
timeout = I2C_TIMEOUT;
while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET) // PROBLEM HERE!!!!!!!!!!!!!!!
{
if((timeout--) == 0) return 0;
}
....
....
}
OK,I found the problem. Flag I2C_ISR_TXIS did not get because the device on the i2c did not respond to the sent address. Need to convert the device address to 7 bits.
(DeviceAddr & 0x7f) << 1