void DMA1_Channel1_IRQHandler(void) { uint8_t ii; /* Test DMA1 TC flag */ if((DMA_GetFlagStatus(DMA1_FLAG_TC1)) != RESET ) { /* Clear DMA TC flag */ DMA_ClearFlag(DMA1_FLAG_TC1); if(Motor_State==INIT) { ADCTemp_Init(ADC_Tab); } else { //LED_ON(); if(FOC_Flag) { for(ii=0;ii<6;ii++) TPWM_Cnt[ii+1]++; PWM_Cnt++; if(Limit_angle<(ANGLE_60D+ANGLE_60D/8)) { SVM_Angle=SVM_Angle+Delta_angle; Limit_angle+=Delta_angle; } // SVM_Angle_Test=0; // IQ_Reference=0; // ID_Reference=1000; // Test_Hall=HALL_DATA(); SVPWM_2ShuntGetPhaseCurrentValues(&Curr_a_b); Clarke(&Curr_alfa_beta,&Curr_a_b); Park(&Curr_q_d,&Curr_alfa_beta,SVM_Angle); // #ifdef OPEN_I Volt_q_d.qV_Component1=VQ_Reference; #else Volt_q_d.qV_Component1=PID_Regulator(IQ_Reference,Curr_q_d.qI_Component1,&IQ_PID_t); // #endif Volt_q_d.qV_Component2=PID_Regulator(ID_Reference,Curr_q_d.qI_Component2,&ID_PID_t); RevPark_Circle_Limitation(&Volt_q_d); Rev_Park(&Volt_alfa_beta,&Volt_q_d); SVPWM_2ShuntCalcDutyCycles(&Volt_alfa_beta); } else PWM_Cnt=1000; //LED_OFF(); DAC_SetChannel1Data(DAC_Align_12b_R,SVM_Angle/16); } if(++T2ms_Temp>T2MSTEMP) //2ms { T2ms_Temp=0; T2ms_Flag=1; } if(++T100ms_Temp>T100MSTEMP) //100ms { T100ms_Temp=0; T100ms_Flag=1; }else{} } }
/** * @brief Writes buffer of bytes. * @param pBuffer: Buffer of bytes to be sent to the slave. * @param NumByteToWrite: Number of bytes to be sent by the Master. * @param Mode: Polling or DMA or Interrupt having the highest priority in the application. * @param SlaveAddress: The address of the slave to be addressed by the Master. * @retval : None. */ Status I2C_Master_BufferWrite(uint8_t* pBuffer, uint32_t NumByteToWrite, uint8_t SlaveAddress ) { __IO uint32_t temp = 0; __IO uint32_t Timeout = 0; /* Enable Error IT (used in all modes: DMA, Polling and Interrupts */ I2C1->CR2 |= I2C_IT_ERR; #if I2C_METHOD == DMA /* I2C1 Master Transmission using DMA */ { Timeout = 0xFFFF; /* Configure the DMA channel for I2C1 transmission */ I2CDMA_Set (pBuffer,NumByteToWrite, I2C_DIRECTION_TX); /* Enable the I2C1 DMA requests */ I2C1->CR2 |= CR2_DMAEN_Set; /* Send START condition */ I2C1->CR1 |= CR1_START_Set; /* Wait until SB flag is set: EV5 */ while ((I2C1->SR1&0x0001) != 0x0001) { if (Timeout-- == 0) return Error; } Timeout = 0xFFFF; /* Send slave address */ /* Reset the address bit0 for write */ SlaveAddress &= OAR1_ADD0_Reset; Address = SlaveAddress; /* Send the slave address */ I2C1->DR = Address; /* Wait until ADDR is set: EV6 */ while ((I2C1->SR1&0x0002) != 0x0002) { if (Timeout-- == 0) return Error; } /* Clear ADDR flag by reading SR2 register */ temp = I2C1->SR2; while (!DMA_GetFlagStatus(DMA1_FLAG_TC6)); DMA_Cmd(DMA1_Channel6, DISABLE); DMA_ClearFlag(DMA1_FLAG_TC6); /* EV8_2: Wait until BTF is set before programming the STOP */ while ((I2C1->SR1 & 0x00004) != 0x000004); /* Program the STOP */ I2C1->CR1 |= CR1_STOP_Set; /* Make sure that the STOP bit is cleared by Hardware */ while ((I2C1->CR1&0x200) == 0x200); } #endif #if I2C_METHOD == POLLING /* I2C1 Master Transmission using Polling */ { Timeout = 0xFFFF; /* Send START condition */ I2C1->CR1 |= CR1_START_Set; /* Wait until SB flag is set: EV5 */ while ((I2C1->SR1&0x0001) != 0x0001) { if (Timeout-- == 0) return Error; } /* Send slave address */ /* Reset the address bit0 for write*/ SlaveAddress &= OAR1_ADD0_Reset; Address = SlaveAddress; /* Send the slave address */ I2C1->DR = Address; Timeout = 0xFFFF; /* Wait until ADDR is set: EV6 */ while ((I2C1->SR1 &0x0002) != 0x0002) { if (Timeout-- == 0) return Error; } /* Clear ADDR flag by reading SR2 register */ temp = I2C1->SR2; /* Write the first data in DR register (EV8_1) */ I2C1->DR = *pBuffer; /* Increment */ pBuffer++; /* Decrement the number of bytes to be written */ NumByteToWrite--; /* While there is data to be written */ while (NumByteToWrite--) { /* Poll on BTF to receive data because in polling mode we can not guarantee the EV8 software sequence is managed before the current byte transfer completes */ Timeout = 0xFFFF; while ((I2C1->SR1 & 0x00004) != 0x000004) { if (Timeout-- == 0) return Error; } /* Send the current byte */ I2C1->DR = *pBuffer; /* Point to the next byte to be written */ pBuffer++; } /* EV8_2: Wait until BTF is set before programming the STOP */ Timeout = 0xFFFF; while ((I2C1->SR1 & 0x00004) != 0x000004) { if (Timeout-- == 0) return Error; } /* Send STOP condition */ I2C1->CR1 |= CR1_STOP_Set; /* Make sure that the STOP bit is cleared by Hardware */ Timeout = 0xFFFF; while ((I2C1->CR1&0x200) == 0x200) { if (Timeout-- == 0) return Error; } } #endif #if I2C_METHOD == INTERRUPT /* I2C1 Master Transmission using Interrupt with highest priority in the application */ { /* Enable EVT IT*/ I2C1->CR2 |= I2C_IT_EVT; /* Enable BUF IT */ I2C1->CR2 |= I2C_IT_BUF; /* Set the I2C direction to Transmission */ I2CDirection = I2C_DIRECTION_TX; SlaveAddress &= OAR1_ADD0_Reset; Address = SlaveAddress; NumbOfBytes = NumByteToRead; /* Send START condition */ I2C1->CR1 |= CR1_START_Set; /* Wait until the START condition is generated on the bus: the START bit is cleared by hardware */ while ((I2C1->CR1&0x100) == 0x100); /* Wait until BUSY flag is reset: a STOP has been generated on the bus signaling the end of transmission */ while ((I2C1->SR2 &0x0002) == 0x0002); } #endif return Success; }
/** * @brief Writes buffer of bytes. * @param pBuffer: Buffer of bytes to be sent to the slave. * @param NumByteToWrite: Number of bytes to be sent by the Master. * @param Mode: Polling or DMA or Interrupt having the highest priority in the application. * @param SlaveAddress: The address of the slave to be addressed by the Master. * @retval : None. */ ErrorStatus I2C_Master_BufferWrite(I2C_TypeDef* I2Cx, uint8_t* pBuffer, uint32_t NumByteToWrite, I2C_ProgrammingModel Mode, uint8_t SlaveAddress, uint32_t timeoutMs) { __IO uint32_t temp = 0; __IO uint32_t Timeout = 0; /* Enable Error IT (used in all modes: DMA, Polling and Interrupts */ I2Cx->CR2 |= I2C_IT_ERR; if (Mode == DMA) /* I2Cx Master Transmission using DMA */ { Timeout = 0xFFFF; /* Configure the DMA channel for I2Cx transmission */ I2C_DMAConfig(I2Cx, pBuffer, NumByteToWrite, I2C_DIRECTION_TX); /* Enable the I2Cx DMA requests */ I2Cx->CR2 |= CR2_DMAEN_Set; /* Send START condition */ I2Cx->CR1 |= CR1_START_Set; /* Wait until SB flag is set: EV5 */ while ((I2Cx->SR1 & 0x0001) != 0x0001) { if (Timeout-- == 0) return ERROR; } Timeout = 0xFFFF; /* Send slave address */ /* Reset the address bit0 for write */ SlaveAddress &= OAR1_ADD0_Reset; Address = SlaveAddress; /* Send the slave address */ I2Cx->DR = Address; /* Wait until ADDR is set: EV6 */ while ((I2Cx->SR1 & 0x0002) != 0x0002) { if (Timeout-- == 0) return ERROR; } /* Clear ADDR flag by reading SR2 register */ temp = I2Cx->SR2; if (I2Cx == I2C1) { /* Wait until DMA end of transfer */ // while (!DMA_GetFlagStatus(DMA1_FLAG_TC6)); xSemaphoreTake(i2cdevDmaEventI2c1, M2T(5)); /* Disable the DMA1 Channel 6 */ DMA_Cmd(I2C1_DMA_CHANNEL_TX, DISABLE); /* Clear the DMA Transfer complete flag */ DMA_ClearFlag(DMA1_FLAG_TC6); } else /* I2Cx = I2C2 */ { /* Wait until DMA end of transfer */ //while (!DMA_GetFlagStatus(DMA1_FLAG_TC4)) xSemaphoreTake(i2cdevDmaEventI2c2, M2T(5)); /* Disable the DMA1 Channel 4 */ DMA_Cmd(I2C2_DMA_CHANNEL_TX, DISABLE); /* Clear the DMA Transfer complete flag */ DMA_ClearFlag(DMA1_FLAG_TC4); } /* EV8_2: Wait until BTF is set before programming the STOP */ while ((I2Cx->SR1 & 0x00004) != 0x000004) ; /* Program the STOP */ I2Cx->CR1 |= CR1_STOP_Set; /* Make sure that the STOP bit is cleared by Hardware */ while ((I2Cx->CR1 & 0x200) == 0x200) ; } /* I2Cx Master Transmission using Interrupt with highest priority in the application */ else { /* Enable EVT IT*/ I2Cx->CR2 |= I2C_IT_EVT; /* Enable BUF IT */ I2Cx->CR2 |= I2C_IT_BUF; /* Set the I2C direction to Transmission */ I2CDirection = I2C_DIRECTION_TX; Buffer_Tx1 = pBuffer; SlaveAddress &= OAR1_ADD0_Reset; Address = SlaveAddress; if (I2Cx == I2C1) NumbOfBytes1 = NumByteToWrite; else NumbOfBytes2 = NumByteToWrite; /* Send START condition */ I2Cx->CR1 |= CR1_START_Set; Timeout = timeoutMs * I2CDEV_LOOPS_PER_MS; /* Wait until the START condition is generated on the bus: the START bit is cleared by hardware */ while ((I2Cx->CR1 & 0x100) == 0x100 && Timeout) { Timeout--; } /* Wait until BUSY flag is reset: a STOP has been generated on the bus signaling the end of transmission */ while ((I2Cx->SR2 & 0x0002) == 0x0002 && Timeout) { Timeout--; } if (Timeout == 0) return ERROR; } return SUCCESS; temp++; //To avoid GCC warning! }
void COMInit(COM_TypeDef COM) { DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; /* Enable GPIO clock */ RCC_AHB1PeriphClockCmd(COM_TX_PORT_CLK[COM] | COM_RX_PORT_CLK[COM] | RCC_AHB1Periph_GPIOD, ENABLE); if (COM == USART_COM1) { /* Enable UART clock */ RCC_APB2PeriphClockCmd(COM_USART_CLK[COM], ENABLE); } /* Connect PXx to USARTx_Tx*/ GPIO_PinAFConfig(COM_TX_PORT[COM], COM_TX_PIN_SOURCE[COM], COM_TX_AF[COM]); /* Connect PXx to USARTx_Rx*/ GPIO_PinAFConfig(COM_RX_PORT[COM], COM_RX_PIN_SOURCE[COM], COM_RX_AF[COM]); /* Configure USART Tx as alternate function */ GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = COM_TX_PIN[COM]; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(COM_TX_PORT[COM], &GPIO_InitStructure); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Pin = COM_RX_PIN[COM]; GPIO_Init(COM_RX_PORT[COM], &GPIO_InitStructure); /*USART Init code*/ USART_OverSampling8Cmd(COM_USART[COM], ENABLE); USART_InitStructure.USART_BaudRate = 115200; 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_Init(COM_USART[COM], &USART_InitStructure); /*USART Interrupt code*/ /*USART TX interrupt*/ NVIC_InitStructure.NVIC_IRQChannel = COM_DMA_TX_IRQn[COM]; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = COM_TX_DMA_PREPRIO[COM]; NVIC_InitStructure.NVIC_IRQChannelSubPriority = COM_TX_DMA_SUBPRIO[COM]; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /*USART RX interrupt*/ NVIC_InitStructure.NVIC_IRQChannel = COM_DMA_RX_IRQn[COM]; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = COM_RX_DMA_PREPRIO[COM]; NVIC_InitStructure.NVIC_IRQChannelSubPriority = COM_RX_DMA_SUBPRIO[COM]; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); RCC_AHB1PeriphClockCmd(COM_DMA_CLK[COM], ENABLE); /*USART TX clean up*/ DMA_ClearFlag(COM_TX_DMA_STREAM[COM], COM_TX_DMA_FLAG_FEIF[COM] | COM_TX_DMA_FLAG_DMEIF[COM] | COM_TX_DMA_FLAG_TEIF[COM] | COM_TX_DMA_FLAG_HTIF[COM] | COM_TX_DMA_FLAG_TCIF[COM]); DMA_Cmd(COM_TX_DMA_STREAM[COM], DISABLE); DMA_DeInit(COM_TX_DMA_STREAM[COM]); /*USART RX Clean up*/ DMA_ClearFlag(COM_RX_DMA_STREAM[COM], COM_RX_DMA_FLAG_FEIF[COM] | COM_RX_DMA_FLAG_DMEIF[COM] | COM_RX_DMA_FLAG_TEIF[COM] | COM_RX_DMA_FLAG_HTIF[COM] | COM_RX_DMA_FLAG_TCIF[COM]); DMA_Cmd(COM_RX_DMA_STREAM[COM], DISABLE); DMA_DeInit(COM_RX_DMA_STREAM[COM]); /*USART TX Config*/ DMA_InitStructure.DMA_Channel = COM_TX_DMA_CHANNEL[COM]; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) COM_DR_ADDRESS[COM]; DMA_InitStructure.DMA_Memory0BaseAddr = COM_TX_BUFFER[COM]; /* This parameter will be configured durig communication */ DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; /* This parameter will be configured durig communication */ DMA_InitStructure.DMA_BufferSize = 0xFF; /* This parameter will be configured durig communication */ DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(COM_TX_DMA_STREAM[COM], &DMA_InitStructure); //DMA_ITConfig(COM_TX_DMA_STREAM[COM], DMA_IT_TC, ENABLE); /*USART RX Config*/ DMA_InitStructure.DMA_Channel = COM_RX_DMA_CHANNEL[COM]; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) COM_DR_ADDRESS[COM]; DMA_InitStructure.DMA_Memory0BaseAddr = COM_RX_BUFFER[COM]; /* This parameter will be configured durig communication */ DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; /* This parameter will be configured durig communication */ DMA_Init(COM_RX_DMA_STREAM[COM], &DMA_InitStructure); //DMA_ITConfig(COM_RX_DMA_STREAM[COM], DMA_IT_TC, ENABLE); /* Enable USART */ USART_Cmd(COM_USART[COM], ENABLE); }
/* * @brief Read the analog value of a pin. * Should return a 16-bit value, 0-65536 (0 = LOW, 65536 = HIGH) * Note: ADC is 12-bit. Currently it returns 0-4096 */ int32_t analogRead(uint16_t pin) { // Allow people to use 0-7 to define analog pins by checking to see if the values are too low. if (pin < FIRST_ANALOG_PIN) { pin = pin + FIRST_ANALOG_PIN; } // SPI safety check if (SPI.isEnabled() == true && (pin == SCK || pin == MOSI || pin == MISO)) { return LOW; } // I2C safety check if (Wire.isEnabled() == true && (pin == SCL || pin == SDA)) { return LOW; } // Serial1 safety check if (Serial1.isEnabled() == true && (pin == RX || pin == TX)) { return LOW; } if (pin >= TOTAL_PINS || PIN_MAP[pin].adc_channel == NONE ) { return LOW; } int i = 0; if (adcChannelConfigured != PIN_MAP[pin].adc_channel) { digitalPinModeSaved = PIN_MAP[pin].pin_mode; pinMode(pin, AN_INPUT); } if (adcInitFirstTime == true) { ADC_DMA_Init(); adcInitFirstTime = false; } if (adcChannelConfigured != PIN_MAP[pin].adc_channel) { // ADC1 regular channel configuration ADC_RegularChannelConfig(ADC1, PIN_MAP[pin].adc_channel, 1, ADC_Sample_Time); // ADC2 regular channel configuration ADC_RegularChannelConfig(ADC2, PIN_MAP[pin].adc_channel, 1, ADC_Sample_Time); // Save the ADC configured channel adcChannelConfigured = PIN_MAP[pin].adc_channel; } for(i = 0 ; i < ADC_DMA_BUFFERSIZE ; i++) { ADC_DualConvertedValues[i] = 0; } // Reset the number of data units in the DMA1 Channel1 transfer DMA_SetCurrDataCounter(DMA1_Channel1, ADC_DMA_BUFFERSIZE); // Enable ADC2 external trigger conversion ADC_ExternalTrigConvCmd(ADC2, ENABLE); // Enable DMA1 Channel1 DMA_Cmd(DMA1_Channel1, ENABLE); // Enable ADC1 DMA ADC_DMACmd(ADC1, ENABLE); // Start ADC1 Software Conversion ADC_SoftwareStartConvCmd(ADC1, ENABLE); // Test on Channel 1 DMA1_FLAG_TC flag while(!DMA_GetFlagStatus(DMA1_FLAG_TC1)); // Clear Channel 1 DMA1_FLAG_TC flag DMA_ClearFlag(DMA1_FLAG_TC1); // Disable ADC1 DMA ADC_DMACmd(ADC1, DISABLE); // Disable DMA1 Channel1 DMA_Cmd(DMA1_Channel1, DISABLE); uint16_t ADC1_ConvertedValue = 0; uint16_t ADC2_ConvertedValue = 0; uint32_t ADC_SummatedValue = 0; uint16_t ADC_AveragedValue = 0; for(int i = 0 ; i < ADC_DMA_BUFFERSIZE ; i++) { // Retrieve the ADC2 converted value and add to ADC_SummatedValue ADC2_ConvertedValue = ADC_DualConvertedValues[i] >> 16; ADC_SummatedValue += ADC2_ConvertedValue; // Retrieve the ADC1 converted value and add to ADC_SummatedValue ADC1_ConvertedValue = ADC_DualConvertedValues[i] & 0xFFFF; ADC_SummatedValue += ADC1_ConvertedValue; } ADC_AveragedValue = (uint16_t)(ADC_SummatedValue / (ADC_DMA_BUFFERSIZE * 2)); // Return ADC averaged value return ADC_AveragedValue; }
/* Envía y recibe datos de 8 bits (SPI-DMA) */ uint8_t SPI_DMA_Transmit8(SPI_TypeDef* SPIx, const uint8_t* pTData, uint8_t* pRData, uint16_t pSize){ uint32_t Dummy = 0xFF; /* Establece el tamaño de 8 bits al bus de datos a transmitir */ SPI_DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; SPI_DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; /* Configura la dirección del Periférico y la cantidad de bytes a escribir */ SPI_DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(SPIx->DR)); SPI_DMA_InitStruct.DMA_BufferSize = pSize; /* 8 bits */ SPI_DataSizeConfig(SPIx, SPI_DataSize_8b); /*********************** TRANSMIT ****************************/ /* Configura el TX DMA */ SPI_DMA_InitStruct.DMA_DIR = SPI_DMA_DIR_TX; /* Memory to Peripheral */ if(pTData){ SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)pTData; SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; }else{ SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&Dummy; SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable; } /* Clear TX DMA1 FLAG y comienza la transmisión */ if(SPIx == SPI1){ DMA_ClearFlag(SPI1_TX_DMA_CHANNEL_FLAG); /* SPI1 */ DMA_Init(SPI1_TX_DMA_CHANNEL,&SPI_DMA_InitStruct); } else if(SPIx == SPI2){ DMA_ClearFlag(SPI2_TX_DMA_CHANNEL_FLAG); /* SPI2 */ DMA_Init(SPI2_TX_DMA_CHANNEL,&SPI_DMA_InitStruct); } #if defined(L152RE) else{ DMA_ClearFlag(SPI3_TX_DMA_CHANNEL_FLAG); /* SPI3 */ DMA_Init(SPI3_TX_DMA_CHANNEL,&SPI_DMA_InitStruct); } #endif /************************** RECEIVE ****************************/ /* Configura el RX DMA */ SPI_DMA_InitStruct.DMA_DIR = SPI_DMA_DIR_RX; /* Peripheral to Memory */ if(pRData){ SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)pRData; SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; }else{ SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&Dummy; SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable; } /* Clear RX DMA1 FLAG y comienza la transmisión */ if(SPIx == SPI1){ DMA_ClearFlag(SPI1_RX_DMA_CHANNEL_FLAG); /* SPI1 */ DMA_Init(SPI1_RX_DMA_CHANNEL,&SPI_DMA_InitStruct); } else if(SPIx == SPI2){ DMA_ClearFlag(SPI2_RX_DMA_CHANNEL_FLAG); /* SPI2 */ DMA_Init(SPI2_RX_DMA_CHANNEL,&SPI_DMA_InitStruct); } #if defined(L152RE) else{ DMA_ClearFlag(SPI3_RX_DMA_CHANNEL_FLAG); /* SPI3 */ DMA_Init(SPI3_RX_DMA_CHANNEL,&SPI_DMA_InitStruct); } #endif /************************ HABILITACIÓN **************************/ if(SPIx == SPI1){ DMA_Cmd(SPI1_TX_DMA_CHANNEL,ENABLE); DMA_Cmd(SPI1_RX_DMA_CHANNEL,ENABLE); SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); while ((DMA_GetFlagStatus(SPI1_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI1)); DMA_Cmd(SPI1_TX_DMA_CHANNEL,DISABLE); DMA_Cmd(SPI1_RX_DMA_CHANNEL,DISABLE); CLEAR_BIT(SPIx->CR2, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN); } else if(SPIx == SPI2){ DMA_Cmd(SPI2_TX_DMA_CHANNEL,ENABLE); DMA_Cmd(SPI2_RX_DMA_CHANNEL,ENABLE); SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); while ((DMA_GetFlagStatus(SPI2_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI2)); DMA_Cmd(SPI2_TX_DMA_CHANNEL,DISABLE); DMA_Cmd(SPI2_RX_DMA_CHANNEL,DISABLE); CLEAR_BIT(SPIx->CR2, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN); } #if defined(L152RE) else{ DMA_Cmd(SPI3_TX_DMA_CHANNEL,ENABLE); DMA_Cmd(SPI3_RX_DMA_CHANNEL,ENABLE); SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); while ((DMA_GetFlagStatus(SPI3_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI3)); DMA_Cmd(SPI3_TX_DMA_CHANNEL,DISABLE); DMA_Cmd(SPI3_RX_DMA_CHANNEL,DISABLE); CLEAR_BIT(SPIx->CR2, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN); } #endif return 1; }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System clocks configuration ---------------------------------------------*/ RCC_Configuration(); /* NVIC configuration ------------------------------------------------------*/ NVIC_Configuration(); /* GPIO configuration ------------------------------------------------------*/ GPIO_Configuration(); /* TIM1 configuration ------------------------------------------------------*/ /* Time Base configuration */ TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIM_Period = 0xFF; TIM_TimeBaseStructure.TIM_Prescaler = 0x4; TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); /* TIM1 channel1 configuration in PWM mode */ TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0x7F; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; TIM_OC1Init(TIM1, &TIM_OCInitStructure); /* DMA1 Channel1 Configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_RegularConvertedValueTab; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 32; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel14 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_13Cycles5); /* Set injected sequencer length */ ADC_InjectedSequencerLengthConfig(ADC1, 1); /* ADC1 injected channel Configuration */ ADC_InjectedChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_71Cycles5); /* ADC1 injected external trigger configuration */ ADC_ExternalTrigInjectedConvConfig(ADC1, ADC_ExternalTrigInjecConv_None); /* Enable automatic injected conversion start after regular one */ ADC_AutoInjectedConvCmd(ADC1, ENABLE); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* Enable ADC1 external trigger */ ADC_ExternalTrigConvCmd(ADC1, ENABLE); /* Enable JEOC interrupt */ ADC_ITConfig(ADC1, ADC_IT_JEOC, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable ADC1 reset calibration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* TIM1 counter enable */ TIM_Cmd(TIM1, ENABLE); /* TIM1 main Output Enable */ TIM_CtrlPWMOutputs(TIM1, ENABLE); /* Test on channel1 transfer complete flag */ while(!DMA_GetFlagStatus(DMA1_FLAG_TC1)); /* Clear channel1 transfer complete flag */ DMA_ClearFlag(DMA1_FLAG_TC1); /* TIM1 counter disable */ TIM_Cmd(TIM1, DISABLE); while (1) { } }
void SPIData_DMA_Enable(FunctionalState isEnable) { DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0); DMA_Cmd(DMA2_Stream0,isEnable); }
/** * @brief Read the configuration register from the LM75. * @param None * @retval LM75 configuration register value. */ uint8_t LM75_ReadConfReg(void) { uint8_t LM75_BufferRX[2] ={0,0}; /* Test on BUSY Flag */ LM75_Timeout = LM75_LONG_TIMEOUT; while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BUSY)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Configure DMA Peripheral */ LM75_DMA_Config(LM75_DMA_RX, (uint8_t*)LM75_BufferRX, 2); /* Enable DMA NACK automatic generation */ I2C_DMALastTransferCmd(LM75_I2C, ENABLE); /* Enable the I2C peripheral */ I2C_GenerateSTART(LM75_I2C, ENABLE); /* Test on SB Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send device address for write */ I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter); /* Test on ADDR Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send the device's internal address to write to */ I2C_SendData(LM75_I2C, LM75_REG_CONF); /* Test on TXE FLag (data sent) */ LM75_Timeout = LM75_FLAG_TIMEOUT; while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF))) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send START condition a second time */ I2C_GenerateSTART(LM75_I2C, ENABLE); /* Test on SB Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send LM75 address for read */ I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Receiver); /* Test on ADDR Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Enable I2C DMA request */ I2C_DMACmd(LM75_I2C,ENABLE); /* Enable DMA RX Channel */ DMA_Cmd(LM75_DMA_RX_CHANNEL, ENABLE); /* Wait until DMA Transfer Complete */ LM75_Timeout = LM75_LONG_TIMEOUT; while (!DMA_GetFlagStatus(LM75_DMA_RX_TCFLAG)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send STOP Condition */ I2C_GenerateSTOP(LM75_I2C, ENABLE); /* Disable DMA RX Channel */ DMA_Cmd(LM75_DMA_RX_CHANNEL, DISABLE); /* Disable I2C DMA request */ I2C_DMACmd(LM75_I2C,DISABLE); /* Clear DMA RX Transfer Complete Flag */ DMA_ClearFlag(LM75_DMA_RX_TCFLAG); /*!< Return Temperature value */ return (uint8_t)LM75_BufferRX[0]; }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. */ /* SPI configuration */ SPI_Config(); /* SysTick configuration */ SysTickConfig(); /* Initialize LEDs mounted on EVAL board */ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED4); #ifdef SPI_MASTER /* Master board configuration */ /* Initializes the SPI communication */ SPI_InitStructure.SPI_Mode = SPI_Mode_Master; SPI_Init(SPIx, &SPI_InitStructure); /* The Data transfer is performed in the SPI using Direct Memory Access */ /* Enable DMA SPI TX Stream */ DMA_Cmd(SPIx_TX_DMA_STREAM,ENABLE); /* Enable DMA SPI RX Stream */ DMA_Cmd(SPIx_RX_DMA_STREAM,ENABLE); /* Enable SPI DMA TX Requsts */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, ENABLE); /* Enable SPI DMA RX Requsts */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE); /* Configure the Tamper Button */ STM_EVAL_PBInit(BUTTON_TAMPER,BUTTON_MODE_GPIO); /* Wait until Tamper Button is pressed */ while (STM_EVAL_PBGetState(BUTTON_TAMPER)); /* Enable the SPI peripheral */ SPI_Cmd(SPIx, ENABLE); #endif /* SPI_MASTER */ #ifdef SPI_SLAVE /* Slave board configuration */ /* Initializes the SPI communication */ SPI_InitStructure.SPI_Mode = SPI_Mode_Slave; SPI_Init(SPIx, &SPI_InitStructure); /* Enable DMA SPI TX Stream */ DMA_Cmd(SPIx_TX_DMA_STREAM,ENABLE); /* Enable DMA SPI RX Stream */ DMA_Cmd(SPIx_RX_DMA_STREAM,ENABLE); /* Enable SPI DMA TX Requsts */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, ENABLE); /* Enable SPI DMA RX Requsts */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, ENABLE); /* Enable the SPI peripheral */ SPI_Cmd(SPIx, ENABLE); #endif /* SPI_SLAVE */ /* Waiting the end of Data transfer */ while (DMA_GetFlagStatus(SPIx_TX_DMA_STREAM,SPIx_TX_DMA_FLAG_TCIF)==RESET); while (DMA_GetFlagStatus(SPIx_RX_DMA_STREAM,SPIx_RX_DMA_FLAG_TCIF)==RESET); /* Clear DMA Transfer Complete Flags */ DMA_ClearFlag(SPIx_TX_DMA_STREAM,SPIx_TX_DMA_FLAG_TCIF); DMA_ClearFlag(SPIx_RX_DMA_STREAM,SPIx_RX_DMA_FLAG_TCIF); /* Disable DMA SPI TX Stream */ DMA_Cmd(SPIx_TX_DMA_STREAM,DISABLE); /* Disable DMA SPI RX Stream */ DMA_Cmd(SPIx_RX_DMA_STREAM,DISABLE); /* Disable SPI DMA TX Requsts */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Tx, DISABLE); /* Disable SPI DMA RX Requsts */ SPI_I2S_DMACmd(SPIx, SPI_I2S_DMAReq_Rx, DISABLE); /* Disable the SPI peripheral */ SPI_Cmd(SPIx, DISABLE); if (Buffercmp(aTxBuffer, aRxBuffer, BUFFERSIZE) != FAILED) { /* Turn ON LED1 and LED3 */ STM_EVAL_LEDOn(LED1); STM_EVAL_LEDOn(LED3); /* Turn OFF LED2 and LED4 */ STM_EVAL_LEDOff(LED2); STM_EVAL_LEDOff(LED4); } else { /* Turn OFF LED1 and LED3 */ STM_EVAL_LEDOff(LED1); STM_EVAL_LEDOff(LED3); /* Turn ON LED2 and LED4 */ STM_EVAL_LEDOn(LED2); STM_EVAL_LEDOn(LED4); } /* Infinite Loop */ while (1) { } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* USART configuration -----------------------------------------------------*/ USART_Config(); /* SysTick configuration ---------------------------------------------------*/ SysTickConfig(); /* LEDs configuration ------------------------------------------------------*/ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); STM_EVAL_LEDInit(LED3); #ifdef USART_TRANSMITTER /* Tamper Button Configuration ---------------------------------------------*/ STM_EVAL_PBInit(BUTTON_TAMPER,BUTTON_MODE_GPIO); /* Enable DMA USART TX Stream */ DMA_Cmd(USARTx_TX_DMA_STREAM,ENABLE); /* Wait until Tamper Button is pressed */ while (STM_EVAL_PBGetState(BUTTON_TAMPER)); /* Enable USART DMA TX Requsts */ USART_DMACmd(USARTx, USART_DMAReq_Tx, ENABLE); /* Waiting the end of Data transfer */ while (USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET); while (DMA_GetFlagStatus(USARTx_TX_DMA_STREAM,USARTx_TX_DMA_FLAG_TCIF)==RESET); /* Clear DMA Transfer Complete Flags */ DMA_ClearFlag(USARTx_TX_DMA_STREAM,USARTx_TX_DMA_FLAG_TCIF); /* Clear USART Transfer Complete Flags */ USART_ClearFlag(USARTx,USART_FLAG_TC); #endif /* USART_TRANSMITTER */ #ifdef USART_RECEIVER /* Enable DMA USART RX Stream */ DMA_Cmd(USARTx_RX_DMA_STREAM,ENABLE); /* Enable USART DMA RX Requsts */ USART_DMACmd(USARTx, USART_DMAReq_Rx, ENABLE); /* Waiting the end of Data transfer */ while (USART_GetFlagStatus(USARTx,USART_FLAG_TC)==RESET); while (DMA_GetFlagStatus(USARTx_RX_DMA_STREAM,USARTx_RX_DMA_FLAG_TCIF)==RESET); /* Clear DMA Transfer Complete Flags */ DMA_ClearFlag(USARTx_RX_DMA_STREAM,USARTx_RX_DMA_FLAG_TCIF); /* Clear USART Transfer Complete Flags */ USART_ClearFlag(USARTx,USART_FLAG_TC); if (Buffercmp(aTxBuffer, aRxBuffer, BUFFERSIZE) != FAILED) { /* Turn ON LED2 */ STM_EVAL_LEDOn(LED2); } else { /* Turn ON LED3 */ STM_EVAL_LEDOn(LED3); } #endif /* USART_RECEIVER */ while (1) { } }
/* Only 1 byte READ using Interrupt or Polling otherwise using DMA */ void I2C1_EV_IRQHandler() { __IO uint16_t regSR1, regSR2; __IO uint32_t regSR; int i=10; rt_interrupt_enter(); //rt_hw_led_on(10); regSR1 = I2C1->SR1; regSR2 = I2C1->SR2; regSR = (regSR2 << 16) | regSR1; //rt_kprintf("EV=> SR1: 0x%x\tSR2: 0x%x\tSR: 0x%x status: %d\n", regSR1, regSR2, regSR, i2cStatus); if( (regSR & I2C_EVENT_MASTER_MODE_SELECT) == I2C_EVENT_MASTER_MODE_SELECT) //EV5 { if( i2cStatus == S1 ) //Send TX Command { I2C1->DR = DevAddr & 0xFE; i2cStatus = S2; } else if( i2cStatus == S4 ) //Send RX Command { I2C1->DR = DevAddr | 0x01; i2cStatus = S5; } regSR1 = 0; regSR2 = 0; } if( (regSR & I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)== I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) //EV6 { switch( i2cStatus ) { case S2: //Send 1st memory address phase { //I2C_DMACmd(I2C1, ENABLE); I2C1->DR = MemAddr[0]; if( memtype == I2C_MEM_1Byte ) i2cStatus = S2_2; else if( memtype == I2C_MEM_2Bytes ) i2cStatus = S2_1; } break; case S5: //Set RX buffer phase { if( i2cFlag == I2C_READ_DMA ) { I2C_DMAConfig(I2C1, i2c_buf, BufSize, I2C_DIRECTION_RX); I2C1->CR2 |= CR2_LAST_Set | CR2_DMAEN_Set; DMA_ITConfig( I2C1_DMA_CHANNEL_RX, DMA_IT_TC, ENABLE); } else if( i2cFlag == I2C_READ_INTERRUPT ) { I2C1->CR2 |= I2C_IT_BUF; I2C1->CR1 &= CR1_ACK_Reset; /* Program the STOP */ I2C1->CR1 |= CR1_STOP_Set; } i2cStatus = S6; } break; } regSR1 = 0; regSR2 = 0; //dump_i2c_register(I2C1); } if((regSR & I2C_EVENT_MASTER_BYTE_RECEIVED) == I2C_EVENT_MASTER_BYTE_RECEIVED) //EV7 { //Interrupt RX complete phase if( i2cStatus == S6 && i2cFlag == I2C_READ_INTERRUPT ) { *i2c_buf = I2C1->DR; i2cStatus = S_STOP; rt_event_send(&i2c_event, I2C_COMPLETE); } } if( (regSR & I2C_EVENT_MASTER_BYTE_TRANSMITTED) == I2C_EVENT_MASTER_BYTE_TRANSMITTED ) //EV8_2 { //Start TX/RX phase if(i2cStatus == S3) { DMA_ClearFlag(I2C1_DMA_CHANNEL_TX, DMA_FLAG_TCIF6 ); DMA_Cmd(I2C1_DMA_CHANNEL_TX, DISABLE); switch (i2cFlag) { case I2C_WRITE: i2cStatus = S_STOP; I2C1->CR1 |= CR1_STOP_Set; rt_event_send(&i2c_event, I2C_COMPLETE); break; case I2C_READ_DMA: i2cStatus = S4; I2C1->CR1 |= CR1_START_Set; break; case I2C_READ_POLLING: i2cStatus = S_STOP; rt_event_send(&i2c_event, I2C_COMPLETE); I2C1->CR2 &= ~(CR2_LAST_Set | I2C_IT_EVT | CR2_DMAEN_Set); I2C1->CR1 |= CR1_START_Set; break; case I2C_READ_INTERRUPT: i2cStatus = S4; I2C1->CR1 |= CR1_START_Set; break; } } if( i2cStatus == S2_1 ) //Send 2nd memory address { if( memtype == I2C_MEM_2Bytes ) //memory address has 2 bytes { I2C1->DR = MemAddr[1]; i2cStatus = S2_2; } if( i2cFlag == I2C_READ_POLLING || i2cFlag == I2C_READ_DMA || i2cFlag == I2C_READ_INTERRUPT) { i2cStatus = S3; } } if( i2cStatus == S2_2 ) //Set TX DAM phase { I2C_DMAConfig(I2C1, i2c_buf, BufSize, I2C_DIRECTION_TX); I2C1->CR2 |= CR2_DMAEN_Set; i2cStatus = S3; } } rt_interrupt_leave(); }
serialPort_t *serialOpen(USART_TypeDef *USARTx, unsigned int baud, uint16_t flowControl, unsigned int rxBufSize, unsigned int txBufSize) { DMA_InitTypeDef DMA_InitStructure; serialPort_t *s = 0; // Enable USART clocks/ports #ifdef SERIAL_UART1_PORT if (USARTx == USART1) { s = serialUSART1(flowControl, rxBufSize, txBufSize); } #endif #ifdef SERIAL_UART2_PORT if (USARTx == USART2) { s = serialUSART2(flowControl, rxBufSize, txBufSize); } #endif #ifdef SERIAL_UART3_PORT if (USARTx == USART3) { s = serialUSART3(flowControl, rxBufSize, txBufSize); } #endif #ifdef SERIAL_UART4_PORT if (USARTx == UART4) { s = serialUSART4(flowControl, rxBufSize, txBufSize); } #endif #ifdef SERIAL_UART5_PORT if (USARTx == UART5) { s = serialUSART5(flowControl, rxBufSize, txBufSize); } #endif #ifdef SERIAL_UART6_PORT if (USARTx == USART6) { s = serialUSART6(flowControl, rxBufSize, txBufSize); } #endif s->waitFlag = CoCreateFlag(0, 0); // manual reset s->USARTx = USARTx; s->rxHead = s->rxTail = 0; s->txHead = s->txTail = 0; s->baudRate = baud; s->flowControl = flowControl; s->parity = USART_Parity_No; s->stopBits = USART_StopBits_1; serialOpenUART(s); DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)USARTx + 0x04; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Priority = DMA_Priority_Low; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; // Configure DMA for rx if (s->rxDMAStream) { DMA_DeInit(s->rxDMAStream); DMA_InitStructure.DMA_Channel = s->rxDMAChannel; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)s->rxBuf; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = s->rxBufSize; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(s->rxDMAStream, &DMA_InitStructure); DMA_ClearFlag(s->rxDMAStream, s->rxDmaFlags); DMA_Cmd(s->rxDMAStream, ENABLE); USART_DMACmd(USARTx, USART_DMAReq_Rx, ENABLE); s->rxPos = DMA_GetCurrDataCounter(s->rxDMAStream); } // otherwise use ISR else { USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); } // Configure DMA for tx if (s->txDMAStream) { DMA_DeInit(s->txDMAStream); DMA_InitStructure.DMA_Channel = s->txDMAChannel; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_BufferSize = (s->txBufSize != 0) ? s->txBufSize : 16; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(s->txDMAStream, &DMA_InitStructure); DMA_SetCurrDataCounter(s->txDMAStream, 0); DMA_ITConfig(s->txDMAStream, DMA_IT_TC, ENABLE); USART_DMACmd(USARTx, USART_DMAReq_Tx, ENABLE); } // otherwise use ISR else { USART_ITConfig(USARTx, USART_IT_TXE, ENABLE); } // use this port for STDIO if not already defined if (serialSTDIO == 0) serialSTDIO = s; return s; }
void USART3_IRQHandler(void) { volatile u32 tem_reg; volatile u16 u16BufferUsedLen = 0; BaseType_t xHigherPriorityTaskWoken, xResult; // xHigherPriorityTaskWoken must be initialised to pdFALSE. xHigherPriorityTaskWoken = pdFALSE; // error happen if(USART_GetITStatus(USART3, USART_IT_PE) != RESET) { USART_ClearITPendingBit(USART3, USART_IT_PE); xSerialRxParityFlag = DMA_UART_PACKET_PARITY_ERR; } // uart idle interrupt if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET) { USART_ClearITPendingBit(USART3, USART_IT_IDLE); DMA_ClearFlag(DMA1_FLAG_GL3);//clear all interrupt flags DMA_Cmd(DMA1_Channel3, DISABLE); //close DMA incase receive data while handling xResult = xSemaphoreTakeFromISR( xSerialRxHandleLock, &xHigherPriorityTaskWoken); if( pdTRUE == xResult) { if (uart3_rx_dma_buf.IdleBufferIndex) //buf1 busy, buf2 idle { u16BufferUsedLen = uart3_rx_dma_buf.nBuff1MaxLength - DMA_GetCurrDataCounter(DMA1_Channel3); if (u16BufferUsedLen > 0) { uart3_rx_dma_buf.nBuff1Offset = u16BufferUsedLen; DMA1_Channel3->CMAR = (uint32_t)uart3_rx_dma_buf.pPingPongBuff2; DMA1_Channel3->CNDTR = uart3_rx_dma_buf.nBuff2MaxLength; uart3_rx_dma_buf.IdleBufferIndex = 0; } } else { u16BufferUsedLen = uart3_rx_dma_buf.nBuff2MaxLength - DMA_GetCurrDataCounter(DMA1_Channel3); if (u16BufferUsedLen > 0) { uart3_rx_dma_buf.nBuff2Offset = u16BufferUsedLen; DMA1_Channel3->CMAR = (uint32_t)uart3_rx_dma_buf.pPingPongBuff1; DMA1_Channel3->CNDTR = uart3_rx_dma_buf.nBuff1MaxLength; uart3_rx_dma_buf.IdleBufferIndex = 1; } } xResult = xSemaphoreGiveFromISR( xSerialRxHandleLock ,&xHigherPriorityTaskWoken); if (u16BufferUsedLen > 0) { //boardcast message to handle xResult = xEventGroupSetBitsFromISR( xUart3RxEventGroup, // The event group being updated. UART_DMA_RX_INCOMPLETE_EVENT_BIT,// The bits being set. &xHigherPriorityTaskWoken ); } //End if u16BufferUsedLen > 0 }// End if pdTRUE == xSemaphoreTakeFromISR DMA_Cmd(DMA1_Channel3, ENABLE); //open DMA after handled //clear Idle flag by read SR and DR tem_reg = USART3->SR; tem_reg = USART3->DR; tem_reg = tem_reg; // slove warning }// End if USART_IT_IDLE if(USART_GetITStatus(USART3, USART_IT_FE | USART_IT_NE) != RESET) { USART_ClearITPendingBit(USART3, USART_IT_FE | USART_IT_NE); } if( xResult == pdPASS ) { // If xHigherPriorityTaskWoken is now set to pdTRUE then a context // switch should be requested. The macro used is port specific and // will be either portYIELD_FROM_ISR() or portEND_SWITCHING_ISR() - // refer to the documentation page for the port being used. portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); } }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f10x_xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f10x.c file */ /* System clocks configuration ---------------------------------------------*/ RCC_Configuration(); /* GPIO configuration ------------------------------------------------------*/ GPIO_Configuration(); /* DMA1 channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DualConvertedValueTab; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 16; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel1, &DMA_InitStructure); /* Enable DMA1 Channel1 */ DMA_Cmd(DMA1_Channel1, ENABLE); /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2; ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channels configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 2, ADC_SampleTime_239Cycles5); /* Enable ADC1 DMA */ ADC_DMACmd(ADC1, ENABLE); /* ADC2 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_RegSimult; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 2; ADC_Init(ADC2, &ADC_InitStructure); /* ADC2 regular channels configuration */ ADC_RegularChannelConfig(ADC2, ADC_Channel_11, 1, ADC_SampleTime_239Cycles5); ADC_RegularChannelConfig(ADC2, ADC_Channel_12, 2, ADC_SampleTime_239Cycles5); /* Enable ADC2 external trigger conversion */ ADC_ExternalTrigConvCmd(ADC2, ENABLE); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); /* Enable Vrefint channel17 */ ADC_TempSensorVrefintCmd(ENABLE); /* Enable ADC1 reset calibaration register */ ADC_ResetCalibration(ADC1); /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1)); /* Start ADC1 calibaration */ ADC_StartCalibration(ADC1); /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); /* Enable ADC2 */ ADC_Cmd(ADC2, ENABLE); /* Enable ADC2 reset calibaration register */ ADC_ResetCalibration(ADC2); /* Check the end of ADC2 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC2)); /* Start ADC2 calibaration */ ADC_StartCalibration(ADC2); /* Check the end of ADC2 calibration */ while(ADC_GetCalibrationStatus(ADC2)); /* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); /* Test on DMA1 channel1 transfer complete flag */ while(!DMA_GetFlagStatus(DMA1_FLAG_TC1)); /* Clear DMA1 channel1 transfer complete flag */ DMA_ClearFlag(DMA1_FLAG_TC1); while (1) { } }
/** * @brief Write to the configuration register of the LM75. * @param RegValue: sepecifies the value to be written to LM75 configuration * register. * @retval None */ uint8_t LM75_WriteConfReg(uint8_t RegValue) { uint8_t LM75_BufferTX = 0; LM75_BufferTX = (uint8_t)(RegValue); /* Test on BUSY Flag */ LM75_Timeout = LM75_LONG_TIMEOUT; while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BUSY)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Configure DMA Peripheral */ LM75_DMA_Config(LM75_DMA_TX, (uint8_t*)(&LM75_BufferTX), 1); /* Enable the I2C peripheral */ I2C_GenerateSTART(LM75_I2C, ENABLE); /* Test on SB Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB) == RESET) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter); /* Test on ADDR Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Transmit the first address for r/w operations */ I2C_SendData(LM75_I2C, LM75_REG_CONF); /* Test on TXE FLag (data sent) */ LM75_Timeout = LM75_FLAG_TIMEOUT; while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF))) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Enable I2C DMA request */ I2C_DMACmd(LM75_I2C,ENABLE); /* Enable DMA TX Channel */ DMA_Cmd(LM75_DMA_TX_CHANNEL, ENABLE); /* Wait until DMA Transfer Complete */ LM75_Timeout = LM75_LONG_TIMEOUT; while (!DMA_GetFlagStatus(LM75_DMA_TX_TCFLAG)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Wait until BTF Flag is set before generating STOP */ LM75_Timeout = LM75_LONG_TIMEOUT; while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF))) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send STOP Condition */ I2C_GenerateSTOP(LM75_I2C, ENABLE); /* Disable DMA TX Channel */ DMA_Cmd(LM75_DMA_TX_CHANNEL, DISABLE); /* Disable I2C DMA request */ I2C_DMACmd(LM75_I2C,DISABLE); /* Clear DMA TX Transfer Complete Flag */ DMA_ClearFlag(LM75_DMA_TX_TCFLAG); return LM75_OK; }
/** * @brief Initializes peripherals used by the I2C EEPROM driver. * @param None * @retval None */ void sEE_LowLevel_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; /*!< sEE_I2C Periph clock enable */ RCC_APB1PeriphClockCmd(sEE_I2C_CLK, ENABLE); /*!< sEE_I2C_SCL_GPIO_CLK and sEE_I2C_SDA_GPIO_CLK Periph clock enable */ RCC_AHB1PeriphClockCmd(sEE_I2C_SCL_GPIO_CLK | sEE_I2C_SDA_GPIO_CLK, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); /* Reset sEE_I2C IP */ RCC_APB1PeriphResetCmd(sEE_I2C_CLK, ENABLE); /* Release reset signal of sEE_I2C IP */ RCC_APB1PeriphResetCmd(sEE_I2C_CLK, DISABLE); /*!< GPIO configuration */ /* Connect PXx to I2C_SCL*/ GPIO_PinAFConfig(sEE_I2C_SCL_GPIO_PORT, sEE_I2C_SCL_SOURCE, sEE_I2C_SCL_AF); /* Connect PXx to I2C_SDA*/ GPIO_PinAFConfig(sEE_I2C_SDA_GPIO_PORT, sEE_I2C_SDA_SOURCE, sEE_I2C_SDA_AF); /*!< Configure sEE_I2C pins: SCL */ GPIO_InitStructure.GPIO_Pin = sEE_I2C_SCL_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(sEE_I2C_SCL_GPIO_PORT, &GPIO_InitStructure); /*!< Configure sEE_I2C pins: SDA */ GPIO_InitStructure.GPIO_Pin = sEE_I2C_SDA_PIN; GPIO_Init(sEE_I2C_SDA_GPIO_PORT, &GPIO_InitStructure); /* Configure and enable I2C DMA TX Channel interrupt */ NVIC_InitStructure.NVIC_IRQChannel = sEE_I2C_DMA_TX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = sEE_I2C_DMA_PREPRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = sEE_I2C_DMA_SUBPRIO; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Configure and enable I2C DMA RX Channel interrupt */ NVIC_InitStructure.NVIC_IRQChannel = sEE_I2C_DMA_RX_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = sEE_I2C_DMA_PREPRIO; NVIC_InitStructure.NVIC_IRQChannelSubPriority = sEE_I2C_DMA_SUBPRIO; NVIC_Init(&NVIC_InitStructure); /*!< I2C DMA TX and RX channels configuration */ /* Enable the DMA clock */ RCC_AHB1PeriphClockCmd(sEE_I2C_DMA_CLK, ENABLE); /* Clear any pending flag on Rx Stream */ DMA_ClearFlag(sEE_I2C_DMA_STREAM_TX, sEE_TX_DMA_FLAG_FEIF | sEE_TX_DMA_FLAG_DMEIF | sEE_TX_DMA_FLAG_TEIF | \ sEE_TX_DMA_FLAG_HTIF | sEE_TX_DMA_FLAG_TCIF); /* Disable the EE I2C Tx DMA stream */ DMA_Cmd(sEE_I2C_DMA_STREAM_TX, DISABLE); /* Configure the DMA stream for the EE I2C peripheral TX direction */ DMA_DeInit(sEE_I2C_DMA_STREAM_TX); sEEDMA_InitStructure.DMA_Channel = sEE_I2C_DMA_CHANNEL; sEEDMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)sEE_I2C_DR_Address; sEEDMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)0; /* This parameter will be configured durig communication */; sEEDMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; /* This parameter will be configured durig communication */ sEEDMA_InitStructure.DMA_BufferSize = 0xFFFF; /* This parameter will be configured durig communication */ sEEDMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; sEEDMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; sEEDMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; sEEDMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; sEEDMA_InitStructure.DMA_Mode = DMA_Mode_Normal; sEEDMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; sEEDMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable; sEEDMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; sEEDMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; sEEDMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(sEE_I2C_DMA_STREAM_TX, &sEEDMA_InitStructure); /* Clear any pending flag on Rx Stream */ DMA_ClearFlag(sEE_I2C_DMA_STREAM_RX, sEE_RX_DMA_FLAG_FEIF | sEE_RX_DMA_FLAG_DMEIF | sEE_RX_DMA_FLAG_TEIF | \ sEE_RX_DMA_FLAG_HTIF | sEE_RX_DMA_FLAG_TCIF); /* Disable the EE I2C DMA Rx stream */ DMA_Cmd(sEE_I2C_DMA_STREAM_RX, DISABLE); /* Configure the DMA stream for the EE I2C peripheral RX direction */ DMA_DeInit(sEE_I2C_DMA_STREAM_RX); DMA_Init(sEE_I2C_DMA_STREAM_RX, &sEEDMA_InitStructure); /* Enable the DMA Channels Interrupts */ DMA_ITConfig(sEE_I2C_DMA_STREAM_TX, DMA_IT_TC, ENABLE); DMA_ITConfig(sEE_I2C_DMA_STREAM_RX, DMA_IT_TC, ENABLE); }
/** * @brief Enables or disables the LM75. * @param NewState: specifies the LM75 new status. This parameter can be ENABLE * or DISABLE. * @retval None */ uint8_t LM75_ShutDown(FunctionalState NewState) { uint8_t LM75_BufferRX[2] ={0,0}; uint8_t LM75_BufferTX = 0; __IO uint8_t RegValue = 0; /* Test on BUSY Flag */ LM75_Timeout = LM75_LONG_TIMEOUT; while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BUSY)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Configure DMA Peripheral */ LM75_DMA_Config(LM75_DMA_RX, (uint8_t*)LM75_BufferRX, 2); /* Enable DMA NACK automatic generation */ I2C_DMALastTransferCmd(LM75_I2C, ENABLE); /* Enable the I2C peripheral */ I2C_GenerateSTART(LM75_I2C, ENABLE); /* Test on SB Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send device address for write */ I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter); /* Test on ADDR Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send the device's internal address to write to */ I2C_SendData(LM75_I2C, LM75_REG_CONF); /* Test on TXE FLag (data sent) */ LM75_Timeout = LM75_FLAG_TIMEOUT; while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF))) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send START condition a second time */ I2C_GenerateSTART(LM75_I2C, ENABLE); /* Test on SB Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send LM75 address for read */ I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Receiver); /* Test on ADDR Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Enable I2C DMA request */ I2C_DMACmd(LM75_I2C,ENABLE); /* Enable DMA RX Channel */ DMA_Cmd(LM75_DMA_RX_CHANNEL, ENABLE); /* Wait until DMA Transfer Complete */ LM75_Timeout = LM75_LONG_TIMEOUT; while (!DMA_GetFlagStatus(LM75_DMA_RX_TCFLAG)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send STOP Condition */ I2C_GenerateSTOP(LM75_I2C, ENABLE); /* Disable DMA RX Channel */ DMA_Cmd(LM75_DMA_RX_CHANNEL, DISABLE); /* Disable I2C DMA request */ I2C_DMACmd(LM75_I2C,DISABLE); /* Clear DMA RX Transfer Complete Flag */ DMA_ClearFlag(LM75_DMA_RX_TCFLAG); /*!< Get received data */ RegValue = (uint8_t)LM75_BufferRX[0]; /*---------------------------- Transmission Phase ---------------------------*/ /*!< Enable or disable SD bit */ if (NewState != DISABLE) { /*!< Enable LM75 */ LM75_BufferTX = RegValue & LM75_SD_RESET; } else { /*!< Disable LM75 */ LM75_BufferTX = RegValue | LM75_SD_SET; } /* Test on BUSY Flag */ LM75_Timeout = LM75_LONG_TIMEOUT; while (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BUSY)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Configure DMA Peripheral */ LM75_DMA_Config(LM75_DMA_TX, (uint8_t*)(&LM75_BufferTX), 1); /* Enable the I2C peripheral */ I2C_GenerateSTART(LM75_I2C, ENABLE); /* Test on SB Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_SB) == RESET) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(LM75_I2C, LM75_ADDR, I2C_Direction_Transmitter); /* Test on ADDR Flag */ LM75_Timeout = LM75_FLAG_TIMEOUT; while (!I2C_CheckEvent(LM75_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Transmit the first address for r/w operations */ I2C_SendData(LM75_I2C, LM75_REG_CONF); /* Test on TXE FLag (data sent) */ LM75_Timeout = LM75_FLAG_TIMEOUT; while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF))) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Enable I2C DMA request */ I2C_DMACmd(LM75_I2C,ENABLE); /* Enable DMA TX Channel */ DMA_Cmd(LM75_DMA_TX_CHANNEL, ENABLE); /* Wait until DMA Transfer Complete */ LM75_Timeout = LM75_LONG_TIMEOUT; while (!DMA_GetFlagStatus(LM75_DMA_TX_TCFLAG)) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Wait until BTF Flag is set before generating STOP */ LM75_Timeout = LM75_LONG_TIMEOUT; while ((!I2C_GetFlagStatus(LM75_I2C,I2C_FLAG_BTF))) { if((LM75_Timeout--) == 0) return LM75_TIMEOUT_UserCallback(); } /* Send STOP Condition */ I2C_GenerateSTOP(LM75_I2C, ENABLE); /* Disable DMA TX Channel */ DMA_Cmd(LM75_DMA_TX_CHANNEL, DISABLE); /* Disable I2C DMA request */ I2C_DMACmd(LM75_I2C,DISABLE); /* Clear DMA TX Transfer Complete Flag */ DMA_ClearFlag(LM75_DMA_TX_TCFLAG); return LM75_OK; }
/* Envía un valor de 16 bits, count veces */ uint16_t SPI_DMA_SendHalfWord(SPI_TypeDef* SPIx, uint16_t value, uint16_t count){ uint16_t dummy = value; uint32_t tmp; /* 16 bits */ SPI_DataSizeConfig(SPIx, SPI_DataSize_16b); /* Establece el tamaño de 16 bits al bus de datos a transmitir */ SPI_DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; SPI_DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; /* Configura la dirección del Periférico y la cantidad de bytes a escribir */ SPI_DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)(&(SPIx->DR)); SPI_DMA_InitStruct.DMA_BufferSize = count; /*********************** TRANSMIT ****************************/ /* Configura el TX DMA */ SPI_DMA_InitStruct.DMA_DIR = SPI_DMA_DIR_TX; /* Memory to Peripheral */ SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&dummy; SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable; /* Clear TX DMA1 FLAG y comienza la transmisión */ if(SPIx == SPI1){ DMA_ClearFlag(SPI1_TX_DMA_CHANNEL_FLAG); /* SPI1 */ DMA_Init(SPI1_TX_DMA_CHANNEL,&SPI_DMA_InitStruct); } else if(SPIx == SPI2){ DMA_ClearFlag(SPI2_TX_DMA_CHANNEL_FLAG); /* SPI2 */ DMA_Init(SPI2_TX_DMA_CHANNEL,&SPI_DMA_InitStruct); } #if defined(L152RE) else{ DMA_ClearFlag(SPI3_TX_DMA_CHANNEL_FLAG); /* SPI3 */ DMA_Init(SPI3_TX_DMA_CHANNEL,&SPI_DMA_InitStruct); } #endif /*************** RECEIVE TO CLEAR BUFFER *****************/ /* Configura el RX DMA */ SPI_DMA_InitStruct.DMA_DIR = SPI_DMA_DIR_RX; /* Peripheral to Memory */ SPI_DMA_InitStruct.DMA_MemoryBaseAddr = (uint32_t)&tmp; SPI_DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable; /* Clear RX DMA1 FLAG y comienza la transmisión */ if(SPIx == SPI1){ DMA_ClearFlag(SPI1_RX_DMA_CHANNEL_FLAG); /* SPI1 */ DMA_Init(SPI1_RX_DMA_CHANNEL,&SPI_DMA_InitStruct); } else if(SPIx == SPI2){ DMA_ClearFlag(SPI2_RX_DMA_CHANNEL_FLAG); /* SPI2 */ DMA_Init(SPI2_RX_DMA_CHANNEL,&SPI_DMA_InitStruct); } #if defined(L152RE) else{ DMA_ClearFlag(SPI3_RX_DMA_CHANNEL_FLAG); /* SPI3 */ DMA_Init(SPI3_RX_DMA_CHANNEL,&SPI_DMA_InitStruct); } #endif /************************ HABILITACIÓN **************************/ if(SPIx == SPI1){ DMA_Cmd(SPI1_TX_DMA_CHANNEL,ENABLE); DMA_Cmd(SPI1_RX_DMA_CHANNEL,ENABLE); SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); while ((DMA_GetFlagStatus(SPI1_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI1)); DMA_Cmd(SPI1_TX_DMA_CHANNEL,DISABLE); DMA_Cmd(SPI1_RX_DMA_CHANNEL,DISABLE); CLEAR_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); } else if(SPIx == SPI2){ DMA_Cmd(SPI2_TX_DMA_CHANNEL,ENABLE); DMA_Cmd(SPI2_RX_DMA_CHANNEL,ENABLE); SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); while ((DMA_GetFlagStatus(SPI2_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI2)); DMA_Cmd(SPI2_TX_DMA_CHANNEL,DISABLE); DMA_Cmd(SPI2_RX_DMA_CHANNEL,DISABLE); CLEAR_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); } #if defined(L152RE) else{ DMA_Cmd(SPI3_TX_DMA_CHANNEL,ENABLE); DMA_Cmd(SPI3_RX_DMA_CHANNEL,ENABLE); SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); while ((DMA_GetFlagStatus(SPI3_RX_DMA_CHANNEL_FLAG) == RESET) | SPI_IS_BUSY(SPI3)); DMA_Cmd(SPI3_TX_DMA_CHANNEL,DISABLE); DMA_Cmd(SPI3_RX_DMA_CHANNEL,DISABLE); CLEAR_BIT(SPIx->CR2, SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN); } #endif return (uint16_t)tmp; }
/** * @brief Writes a value in a register of the device through I2C. * @param DeviceAddr: The address of the IOExpander, could be : IOE_1_ADDR * or IOE_2_ADDR. * @param RegisterAddr: The target register address * @param RegisterValue: The target register value to be written * @retval IOE_OK: if all operations are OK. Other value if error. */ uint8_t I2C_WriteDeviceRegister(uint8_t DeviceAddr, uint8_t RegisterAddr, uint8_t RegisterValue) { uint8_t read_verif = 0; uint8_t IOE_BufferTX = 0; /* Get Value to be written */ IOE_BufferTX = RegisterValue; /* Configure DMA Peripheral */ IOE_DMA_Config(IOE_DMA_TX, (uint8_t*)(&IOE_BufferTX)); /* Enable the I2C peripheral */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on SB Flag */ IOE_TimeOut = TIMEOUT_MAX; while (I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB) == RESET) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter); /* Test on ADDR Flag */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Transmit the first address for r/w operations */ I2C_SendData(IOE_I2C, RegisterAddr); /* Test on TXE FLag (data dent) */ IOE_TimeOut = TIMEOUT_MAX; while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF))) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Enable I2C DMA request */ I2C_DMACmd(IOE_I2C,ENABLE); /* Enable DMA TX Channel */ DMA_Cmd(IOE_DMA_TX_STREAM, ENABLE); /* Wait until DMA Transfer Complete */ IOE_TimeOut = TIMEOUT_MAX; while (!DMA_GetFlagStatus(IOE_DMA_TX_STREAM,IOE_DMA_TX_TCFLAG)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Wait until BTF Flag is set before generating STOP */ IOE_TimeOut = 2 * TIMEOUT_MAX; while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF))) { } /* Send STOP Condition */ I2C_GenerateSTOP(IOE_I2C, ENABLE); /* Disable DMA TX Channel */ DMA_Cmd(IOE_DMA_TX_STREAM, DISABLE); /* Disable I2C DMA request */ I2C_DMACmd(IOE_I2C,DISABLE); /* Clear DMA TX Transfer Complete Flag */ DMA_ClearFlag(IOE_DMA_TX_STREAM,IOE_DMA_TX_TCFLAG); #ifdef VERIFY_WRITTENDATA /* Verify (if needed) that the loaded data is correct */ /* Read the just written register*/ read_verif = I2C_ReadDeviceRegister(DeviceAddr, RegisterAddr); /* Load the register and verify its value */ if (read_verif != RegisterValue) { /* Control data wrongly transfered */ read_verif = IOE_FAILURE; } else { /* Control data correctly transfered */ read_verif = 0; } #endif /* Return the verifying value: 0 (Passed) or 1 (Failed) */ return (read_verif); }
/* This function sends data bytes out to a string of WS2812s * The first argument is a pointer to the first RGB triplet to be sent * The seconds argument is the number of LEDs in the chain * * This will result in the RGB triplet passed by argument 1 being sent to * the LED that is the furthest away from the controller (the point where * data is injected into the chain) */ void WS2812_send(const uint8_t (*color)[3], const uint16_t _len) { int i, j; uint8_t led; uint16_t memaddr; uint16_t buffersize; uint16_t len = _len; // Byte order mapping. 0 is red, 1 is green, 2 is blue const uint8_t pix_map[3] = {0, 2, 1}; buffersize = (len*24); // number of bytes needed is #LEDs * 24 bytes + 42 trailing bytes memaddr = 0; // reset buffer memory index led = 0; // reset led index // fill transmit buffer with correct compare values to achieve // correct pulse widths according to color values while (len) { for (i = 0; i < 3; i++) { for (j = 0; j < 8; j++) // GREEN data { if ( (color[led][pix_map[i]]<<j) & 0x80 ) // data sent MSB first, j = 0 is MSB j = 7 is LSB { LED_BYTE_Buffer[memaddr] = TIM_COMPARE_LOGIC_1; // compare value for logical 1 } else { LED_BYTE_Buffer[memaddr] = TIM_COMPARE_LOGIC_0; // compare value for logical 0 } memaddr++; } } led++; len--; } LED_BYTE_Buffer[memaddr++] = 0; LED_BYTE_Buffer[memaddr++] = 0; // add needed delay at end of byte cycle, pulsewidth = 0 // while(memaddr < buffersize) // { // LED_BYTE_Buffer[memaddr] = 0; // memaddr++; // } DMA_SetCurrDataCounter(DMA_STREAM, buffersize + 2); // load number of bytes to be transferred // PAP: Clear the timer's counter and set the compare value to 0. This // sets the output low on start and gives us a full cycle to set up DMA. TIM_SetCounter(PWM_TIMER, 0); TIM_SetCompare1(PWM_TIMER, 0); TIM_Cmd(PWM_TIMER, ENABLE); // enable Timer 3 // PAP: Start DMA transfer after starting the timer. This prevents the // DMA/PWM from dropping the first bit. DMA_Cmd(DMA_STREAM, ENABLE); // enable DMA channel 6 while(!DMA_GetFlagStatus(DMA_STREAM, DMA_TCIF)); // wait until transfer complete TIM_Cmd(PWM_TIMER, DISABLE); // disable Timer 3 DMA_Cmd(DMA_STREAM, DISABLE); // disable DMA channel 6 DMA_ClearFlag(DMA_STREAM, DMA_TCIF); // clear DMA1 Channel 6 transfer complete flag }
/** * @brief Reads a buffer of 2 bytes from the device registers. * @param DeviceAddr: The address of the device, could be : IOE_1_ADDR * or IOE_2_ADDR. * @param RegisterAddr: The target register address (between 00x and 0x24) * @retval A pointer to the buffer containing the two returned bytes (in halfword). */ uint16_t I2C_ReadDataBuffer(uint8_t DeviceAddr, uint8_t RegisterAddr) { uint8_t tmp= 0; uint8_t IOE_BufferRX[2] = {0x00, 0x00}; /* Configure DMA Peripheral */ IOE_DMA_Config(IOE_DMA_RX, (uint8_t*)IOE_BufferRX); /* Enable DMA NACK automatic generation */ I2C_DMALastTransferCmd(IOE_I2C, ENABLE); /* Enable the I2C peripheral */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on SB Flag */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send device address for write */ I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Transmitter); /* Test on ADDR Flag */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send the device's internal address to write to */ I2C_SendData(IOE_I2C, RegisterAddr); /* Test on TXE FLag (data dent) */ IOE_TimeOut = TIMEOUT_MAX; while ((!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_TXE)) && (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_BTF))) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send START condition a second time */ I2C_GenerateSTART(IOE_I2C, ENABLE); /* Test on SB Flag */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_GetFlagStatus(IOE_I2C,I2C_FLAG_SB)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send IOExpander address for read */ I2C_Send7bitAddress(IOE_I2C, DeviceAddr, I2C_Direction_Receiver); /* Test on ADDR Flag */ IOE_TimeOut = TIMEOUT_MAX; while (!I2C_CheckEvent(IOE_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Enable I2C DMA request */ I2C_DMACmd(IOE_I2C,ENABLE); /* Enable DMA RX Channel */ DMA_Cmd(IOE_DMA_RX_STREAM, ENABLE); /* Wait until DMA Transfer Complete */ IOE_TimeOut = 2 * TIMEOUT_MAX; while (!DMA_GetFlagStatus(IOE_DMA_RX_STREAM, IOE_DMA_RX_TCFLAG)) { if (IOE_TimeOut-- == 0) return(IOE_TimeoutUserCallback()); } /* Send STOP Condition */ I2C_GenerateSTOP(IOE_I2C, ENABLE); /* Disable DMA RX Channel */ DMA_Cmd(IOE_DMA_RX_STREAM, DISABLE); /* Disable I2C DMA request */ I2C_DMACmd(IOE_I2C,DISABLE); /* Clear DMA RX Transfer Complete Flag */ DMA_ClearFlag(IOE_DMA_RX_STREAM,IOE_DMA_RX_TCFLAG); /* Reorganize received data */ tmp = IOE_BufferRX[0]; IOE_BufferRX[0] = IOE_BufferRX[1]; IOE_BufferRX[1] = tmp; /* return a pointer to the IOE_Buffer */ return (*(__IO uint16_t *) IOE_BufferRX); }
/** * @brief Main program * @param None * @retval None */ int main(void) { /*!< At this stage the microcontroller clock setting is already configured, this is done through SystemInit() function which is called from startup file (startup_stm32f4xx.s) before to branch to application main. To reconfigure the default setting of SystemInit() function, refer to system_stm32f4xx.c file */ /* USART configuration -----------------------------------------------------*/ USART_Config(); /* SysTick configuration ---------------------------------------------------*/ SysTickConfig(); /* LEDs configuration ------------------------------------------------------*/ STM_EVAL_LEDInit(LED1); STM_EVAL_LEDInit(LED2); STM_EVAL_LEDInit(LED3); STM_EVAL_LEDInit(LED4); /* IO Expanderconfiguration ------------------------------------------------*/ #ifdef USART_TRANSMITTER_MODE TimeOut = USER_TIMEOUT; while ((IOE_Config() != IOE_OK) && (TimeOut != 0)) { } if(TimeOut == 0) { TimeOut_UserCallback(); } #endif /* USART_TRANSMITTER_MODE */ while (1) { /******************************************************************************/ /* USART in Transmitter Mode */ /******************************************************************************/ #ifdef USART_TRANSMITTER_MODE /* Clear Buffers */ Fill_Buffer(CmdBuffer, 2); DMA_DeInit(USARTx_TX_DMA_STREAM); DMA_InitStructure.DMA_Channel = USARTx_TX_DMA_CHANNEL; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; /****************** USART will Transmit Specific Command ******************/ /* Prepare the DMA to transfer the transaction command (2bytes) from the memory to the USART */ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)CmdBuffer; DMA_InitStructure.DMA_BufferSize = (uint16_t)2; DMA_Init(USARTx_TX_DMA_STREAM, &DMA_InitStructure); /* Prepare Command to be transmitted */ /* Waiting joystick pressed */ PressedButton = JOY_NONE; while (PressedButton == JOY_NONE) { PressedButton = IOE_JoyStickGetState(); } /* Waiting joystick released */ ReleasedButton = IOE_JoyStickGetState(); while ((PressedButton == ReleasedButton) && (ReleasedButton != JOY_NONE)) { ReleasedButton = IOE_JoyStickGetState(); } if(PressedButton != JOY_NONE) { /* For each joystick state correspond a command to be sent through USART */ switch (PressedButton) { /* JOY_RIGHT button pressed */ case JOY_RIGHT: CmdBuffer[0] = CMD_RIGHT; CmdBuffer[1] = CMD_RIGHT_SIZE; break; /* JOY_LEFT button pressed */ case JOY_LEFT: CmdBuffer[0] = CMD_LEFT; CmdBuffer[1] = CMD_LEFT_SIZE; break; /* JOY_UP button pressed */ case JOY_UP: CmdBuffer[0] = CMD_UP; CmdBuffer[1] = CMD_UP_SIZE; break; /* JOY_DOWN button pressed */ case JOY_DOWN: CmdBuffer[0] = CMD_DOWN; CmdBuffer[1] = CMD_DOWN_SIZE; break; /* JOY_SEL button pressed */ case JOY_SEL: CmdBuffer[0] = CMD_SEL; CmdBuffer[1] = CMD_SEL_SIZE; break; default: break; } /* Enable the USART DMA requests */ USART_DMACmd(USARTx, USART_DMAReq_Tx, ENABLE); /* Clear the TC bit in the SR register by writing 0 to it */ USART_ClearFlag(USARTx, USART_FLAG_TC); /* Enable the DMA TX Stream, USART will start sending the command code (2bytes) */ DMA_Cmd(USARTx_TX_DMA_STREAM, ENABLE); /* Wait the USART DMA Tx transfer complete or time out */ TimeOut = USER_TIMEOUT; while ((DMA_GetFlagStatus(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_TCIF) == RESET)&&(TimeOut != 0)) { } if(TimeOut == 0) { TimeOut_UserCallback(); } /* The software must wait until TC=1. The TC flag remains cleared during all data transfers and it is set by hardware at the last frame’s end of transmission*/ TimeOut = USER_TIMEOUT; while ((USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)&&(TimeOut != 0)) { } if(TimeOut == 0) { TimeOut_UserCallback(); } /* Clear DMA Streams flags */ DMA_ClearFlag(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_HTIF | USARTx_TX_DMA_FLAG_TCIF); /* Disable the DMA Streams */ DMA_Cmd(USARTx_TX_DMA_STREAM, DISABLE); /* Disable the USART Tx DMA request */ USART_DMACmd(USARTx, USART_DMAReq_Tx, DISABLE); /******************* USART will Transmit Data Buffer ********************/ /* Prepare the DMA to transfer the transaction data (length defined by CmdBuffer[1] variable) from the memory to the USART */ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)TxBuffer; DMA_InitStructure.DMA_BufferSize = (uint16_t)CmdBuffer[1]; DMA_Init(USARTx_TX_DMA_STREAM, &DMA_InitStructure); /* Enable the USART Tx DMA request */ USART_DMACmd(USARTx, USART_DMAReq_Tx, ENABLE); /* Clear the TC bit in the SR register by writing 0 to it */ USART_ClearFlag(USARTx, USART_FLAG_TC); /* Enable DMA USART Tx Stream */ DMA_Cmd(USARTx_TX_DMA_STREAM, ENABLE); /* Wait the USART DMA Tx transfer complete or time out */ TimeOut = USER_TIMEOUT; while ((DMA_GetFlagStatus(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_TCIF) == RESET)&&(TimeOut != 0)) { } if(TimeOut == 0) { TimeOut_UserCallback(); } /* The software must wait until TC=1, The TC flag remains cleared during all data transfers and it is set by hardware at the last frame’s end of transmission */ TimeOut = USER_TIMEOUT; while ((USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)&&(TimeOut != 0)) { } if(TimeOut == 0) { TimeOut_UserCallback(); } /* Clear all DMA Streams flags */ DMA_ClearFlag(USARTx_TX_DMA_STREAM, USARTx_TX_DMA_FLAG_HTIF | USARTx_TX_DMA_FLAG_TCIF); /* Disable the DMA Stream */ DMA_Cmd(USARTx_TX_DMA_STREAM, DISABLE); /* Disable the USART Tx DMA request */ USART_DMACmd(USARTx, USART_DMAReq_Tx, DISABLE); } #endif /* USART_TRANSMITTER_MODE */ /******************************************************************************/ /* USART in Receiver Mode */ /******************************************************************************/ #ifdef USART_RECEIVER_MODE /* Clear Buffers */ Fill_Buffer(RxBuffer, TXBUFFERSIZE); Fill_Buffer(CmdBuffer, 2); DMA_DeInit(USARTx_RX_DMA_STREAM); DMA_InitStructure.DMA_Channel = USARTx_RX_DMA_CHANNEL; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; /****************** USART will Receive Specific Command *******************/ /* Configure the DMA to receive 2 bytes (transaction command), in case of USART receiver */ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)CmdBuffer; DMA_InitStructure.DMA_BufferSize = (uint16_t)2; DMA_Init(USARTx_RX_DMA_STREAM, &DMA_InitStructure); /* Enable the USART Rx DMA request */ USART_DMACmd(USARTx, USART_DMAReq_Rx, ENABLE); /* Enable the DMA RX Stream */ DMA_Cmd(USARTx_RX_DMA_STREAM, ENABLE); /* Wait the USART DMA Rx transfer complete (to receive the transaction command) */ while (DMA_GetFlagStatus(USARTx_RX_DMA_STREAM, USARTx_RX_DMA_FLAG_TCIF) == RESET) { } /* Clear all DMA Streams flags */ DMA_ClearFlag(USARTx_RX_DMA_STREAM, USARTx_RX_DMA_FLAG_HTIF | USARTx_RX_DMA_FLAG_TCIF); /* Disable the DMA Rx Stream */ DMA_Cmd(USARTx_RX_DMA_STREAM, DISABLE); /* Disable the USART Rx DMA requests */ USART_DMACmd(USARTx, USART_DMAReq_Rx, DISABLE); /************* USART will receive the the transaction data ****************/ /* Transaction data (length defined by CmdBuffer[1] variable) */ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)RxBuffer; DMA_InitStructure.DMA_BufferSize = (uint16_t)CmdBuffer[1]; DMA_Init(USARTx_RX_DMA_STREAM, &DMA_InitStructure); /* Enable the USART Rx DMA requests */ USART_DMACmd(USARTx, USART_DMAReq_Rx , ENABLE); /* Enable the DMA Stream */ DMA_Cmd(USARTx_RX_DMA_STREAM, ENABLE); /* Wait the USART DMA Rx transfer complete or time out */ TimeOut = USER_TIMEOUT; while ((DMA_GetFlagStatus(USARTx_RX_DMA_STREAM, USARTx_RX_DMA_FLAG_TCIF) == RESET)&&(TimeOut != 0)) { } if(TimeOut == 0) { TimeOut_UserCallback(); } /* Clear all DMA Streams flags */ DMA_ClearFlag(USARTx_RX_DMA_STREAM, USARTx_RX_DMA_FLAG_HTIF | USARTx_RX_DMA_FLAG_TCIF); /* Disable the DMA Stream */ DMA_Cmd(USARTx_RX_DMA_STREAM, DISABLE); /* Disable the USART Rx DMA requests */ USART_DMACmd(USARTx, USART_DMAReq_Rx, DISABLE); switch (CmdBuffer[1]) { /* CMD_RIGHT command received */ case CMD_RIGHT_SIZE: if (Buffercmp(TxBuffer, RxBuffer, CMD_RIGHT_SIZE) != FAILED) { /* Turn ON LED2 and LED3 */ STM_EVAL_LEDOn(LED2); STM_EVAL_LEDOn(LED3); /* Turn OFF LED4 */ STM_EVAL_LEDOff(LED4); } break; /* CMD_LEFT command received */ case CMD_LEFT_SIZE: if (Buffercmp(TxBuffer, RxBuffer, CMD_LEFT_SIZE) != FAILED) { /* Turn ON LED4 */ STM_EVAL_LEDOn(LED4); /* Turn OFF LED2 and LED3 */ STM_EVAL_LEDOff(LED2); STM_EVAL_LEDOff(LED3); } break; /* CMD_UP command received */ case CMD_UP_SIZE: if (Buffercmp(TxBuffer, RxBuffer, CMD_UP_SIZE) != FAILED) { /* Turn ON LED2 */ STM_EVAL_LEDOn(LED2); /* Turn OFF LED3 and LED4 */ STM_EVAL_LEDOff(LED3); STM_EVAL_LEDOff(LED4); } break; /* CMD_DOWN command received */ case CMD_DOWN_SIZE: if (Buffercmp(TxBuffer, RxBuffer, CMD_DOWN_SIZE) != FAILED) { /* Turn ON LED3 */ STM_EVAL_LEDOn(LED3); /* Turn OFF LED2 and LED4 */ STM_EVAL_LEDOff(LED2); STM_EVAL_LEDOff(LED4); } break; /* CMD_SEL command received */ case CMD_SEL_SIZE: if (Buffercmp(TxBuffer, RxBuffer, CMD_SEL_SIZE) != FAILED) { /* Turn ON all LED2, LED3 and LED4 */ STM_EVAL_LEDOn(LED2); STM_EVAL_LEDOn(LED3); STM_EVAL_LEDOn(LED4); } break; default: break; } #endif /* USART_RECEIVER_MODE */ } }
/************************************************************************************ * Function Name : MSD_WriteMultipleBlock_DMA(uint32_t sector, uc8 *buffer,u16 NumByteToWrite) * Description : None * Input : - sector: * - buffer: * Output : None * Return : None * Attention : None ************************************************************************************/ int MSD_WriteMultipleBlock_DMA(uint32_t sector, uc8 *buffer, u8 NbrOfSector, u16 NumByteToWrite) { uint8 r1; // uint16_t i=0; uint32_t retry; u8 value = 0; // INT8U err; u8 rvalue = MSD_RESPONSE_FAILURE; DMA_InitTypeDef DMA_InitStructure; //定义DMA初始化结构体 /*begin:yangfei added 2012.11.29*/ // debug("MSD_WriteMultipleBlock_DMA\r\n"); _card_enable(); DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_BufferSize = NumByteToWrite; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel5, &DMA_InitStructure); /* Enable DMA1 Channel5 Transfer Complete interrupt */ DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); /*end:yangfei added 2012.11.29*/ //SPI_DMA_Send_Init(buffer,MSD_BLOCKSIZE); /* if ver = SD2.0 HC, sector need <<9 */ if(CardInfo.CardType != CARDTYPE_SDV2HC) { sector = sector << 9; } if(CardInfo.CardType != CARDTYPE_MMC) { _send_command(ACMD23, NbrOfSector, 0); } /* Send CMD25 : Write multiple block command */ MSD_SendCmd(CMD25, sector, 0xff); //_spi_read_write(DUMMY_BYTE); //_spi_read_write(DUMMY_BYTE); if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR)) { _spi_read_write(DUMMY_BYTE); /* Start data write token: 0xFE */ _spi_read_write(0xFC); /*begin:yangfei added 2012.11.28*/ DMA_Cmd(DMA1_Channel5, ENABLE); #ifdef DMA1_IRQ OSFlagPend(Sem_SD_DMA, (OS_FLAGS)1, OS_FLAG_WAIT_SET_ALL, 0, &err); //请求信号量集的第0位置1 DMA_ClearFlag(DMA1_FLAG_TC5); #else while(!DMA_GetFlagStatus(DMA1_FLAG_TC5)) ; DMA_ClearFlag(DMA1_FLAG_TC5); #endif /* 2Bytes dummy CRC */ _spi_read_write(DUMMY_BYTE); _spi_read_write(DUMMY_BYTE); value = MSD_GetDataResponse(); if (value == MSD_DATA_OK) { rvalue = MSD_RESPONSE_NO_ERROR; } // debug("value=%x\r\n",value); } /* Send end of transmit token: 0xFD */ r1 = _spi_read_write(0xFD); if(r1 == 0x00) { return 4; } /*begin:yangfei added 2012.12.07 for wait programm finished else write error*/ /* Wait all the data programm finished */ retry = 0; while(_spi_read_write(DUMMY_BYTE) == 0x00) { /* Timeout return */ if(retry++ == 0x40000) { _card_disable(); return 3; } } /* chip disable and dummy byte */ _card_disable(); _spi_read_write(DUMMY_BYTE); /*yangfei added*/ DMA_Cmd(DMA1_Channel5, DISABLE); return rvalue; }
/*----------------------------------------- 函数说明:ADC传输DMA2通道0中断服务程序 DMA把AD值传输到缓冲区完成后关闭定 时器3(作为触发AD转换的定时器)同时 置更新完成标志位为1,开定时器3在应 用中开启. ------------------------------------------*/ void DMA2_Stream0_IRQHandler(void) { DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0); //清除DMA传输完成中断 TIM_Cmd(TIM2,DISABLE); //关闭TIM3 }
/******************************************************************************* * Function Name : MSD_ReadSingleBlock * Description : None * Input : - sector: * - buffer: * Output : None * Return : None * Attention : None *******************************************************************************/ int MSD_ReadSingleBlock_DMA(uint32_t sector, uint8_t *buffer) { DMA_InitTypeDef DMA_InitStructure; u8 rvalue = MSD_RESPONSE_FAILURE; uint8_t r1; uint16_t retry; char DuumyClock = DUMMY_BYTE; if(CardInfo.CardType != CARDTYPE_SDV2HC) { sector = sector << 9; } /*initial dma channel 2*/ DMA_DeInit(DMA1_Channel4); DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 200; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &DMA_InitStructure); DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&DuumyClock; //512字节的dummy DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_Low; DMA_Init(DMA1_Channel5, &DMA_InitStructure); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE); // DMA_ClearFlag(DMA_FLAG_TC2); /* Send CMD17 : Read single block command */ r1 = _send_command(CMD17, sector, 0); if(r1 != 0x00) { return 1; } /* Card enable, Prepare to read */ _card_enable(); /* Wait start-token 0xFE */ for(retry = 0; retry < 2000; retry++) { r1 = _spi_read_write(DUMMY_BYTE); if(r1 == 0xFE) { retry = 0; break; } } /* Timeout return */ if(retry == 2000) { _card_disable(); return 1; } DMA_Cmd(DMA1_Channel5, ENABLE); DMA_Cmd(DMA1_Channel4, ENABLE); while(!DMA_GetFlagStatus(DMA1_FLAG_TC5)); while(!DMA_GetFlagStatus(DMA1_FLAG_TC4)); DMA_ClearFlag(DMA1_FLAG_TC4); /* 2bytes dummy CRC */ _spi_read_write(DUMMY_BYTE); _spi_read_write(DUMMY_BYTE); /* chip disable and dummy byte */ _card_disable(); _spi_read_write(DUMMY_BYTE); /* Set response value to success */ rvalue = MSD_RESPONSE_NO_ERROR; DMA_Cmd(DMA1_Channel4, DISABLE); DMA_Cmd(DMA1_Channel5, DISABLE); /* Returns the reponse */ return rvalue; }
Status I2C_Master_BufferRead(uint8_t* pBuffer, uint32_t NumByteToRead, uint8_t SlaveAddress) { __IO uint32_t temp = 0; __IO uint32_t Timeout = 0; /* Enable I2C errors interrupts (used in all modes: Polling, DMA and Interrupts */ I2C1->CR2 |= I2C_IT_ERR; #if I2C_METHOD == DMA /* I2C1 Master Reception using DMA */ { /* Configure I2C1 DMA channel */ I2CDMA_Set(pBuffer,NumByteToRead, I2C_DIRECTION_RX); /* Set Last bit to have a NACK on the last received byte */ I2C1->CR2 |= CR2_LAST_Set; //该位在主接收模式使用, 使得在最后一次接收数据时可以产生一个NACK。 /* Enable I2C DMA requests */ I2C1->CR2 |= CR2_DMAEN_Set; /* Send START condition */ I2C1->CR1 |= CR1_START_Set; /* Wait until SB flag is set: EV5 */ Timeout = 0xFFFF; while ((I2C1->SR1&0x0001) != 0x0001) { if (Timeout-- == 0) return Error; } Timeout = 0xFFFF; /* Send slave address */ /* Set the address bit0 for read */ SlaveAddress |= OAR1_ADD0_Set; Address = SlaveAddress; /* Send the slave address */ I2C1->DR = Address; /* Wait until ADDR is set: EV6 */ while ((I2C1->SR1&0x0002) != 0x0002) { if (Timeout-- == 0) return Error; } /* Clear ADDR flag by reading SR2 register */ temp = I2C1->SR2; // Timeout = 0xFFFF; while (!DMA_GetFlagStatus(DMA1_FLAG_TC7)); // { // if (Timeout-- == 0) // return Error; // } DMA_Cmd(DMA1_Channel7, DISABLE); DMA_ClearFlag(DMA1_FLAG_TC7); /* Program the STOP */ I2C1->CR1 |= CR1_STOP_Set; /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */ Timeout = 0xFFFF; while ((I2C1->CR1&0x200) == 0x200); { if (Timeout-- == 0) return Error; } Deal_I2CComming(); } #endif #if I2C_METHOD == POLLING /* I2C1 Master Reception using Polling */ { Timeout = 0xFFFF; /* Send START condition */ I2C1->CR1 |= CR1_START_Set; /* Wait until SB flag is set: EV5 */ while ((I2C1->SR1&0x0001) != 0x0001) { if (Timeout-- == 0) return Error; } Timeout = 0xFFFF; /* Send slave address */ /* Reset the address bit0 for write */ SlaveAddress |= OAR1_ADD0_Set;; Address = SlaveAddress; /* Send the slave address */ I2C1->DR = Address; /* Wait until ADDR is set: EV6 */ while ((I2C1->SR1&0x0002) != 0x0002) { if (Timeout-- == 0) return Error; } /* Clear ADDR by reading SR2 status register */ temp = I2C1->SR2; /* While there is data to be read */ while (NumByteToRead) { /* Receive bytes from first byte until byte N-3 */ if (NumByteToRead != 3) { /* Poll on BTF to receive data because in polling mode we can not guarantee the EV7 software sequence is managed before the current byte transfer completes */ Timeout=0xFFFF; while ((I2C1->SR1 & 0x00004) != 0x000004) { if (Timeout-- == 0) return Error; } /* Read data */ *pBuffer = I2C1->DR; /* */ pBuffer++; /* Decrement the read bytes counter */ NumByteToRead--; } /* it remains to read three data: data N-2, data N-1, Data N */ if (NumByteToRead == 3) //还剩三字节未读时,关ACK,关中断,读n-2字节,置STOP,读n-1字节,开中断,等字节到达DR,读n字节 //为何不在读完倒数第二字节时候关ACK,读完所有之后stop?实践证明不提前关ACK,读完所有字节后依然会回ACK给从设备, //从设备会继续产生clk,送出一个FF值字节(因为sda此时为高) { /* Wait until BTF is set: Data N-2 in DR and data N -1 in shift register */ while ((I2C1->SR1 & 0x00004) != 0x000004) Timeout-=0xFFFF; { if (Timeout-- == 0) return Error; } /* Clear ACK */ I2C1->CR1 &= CR1_ACK_Reset; /* Disable IRQs around data reading and STOP programming because of the limitation ? */ __disable_irq(); /* Read Data N-2 */ *pBuffer = I2C1->DR; /* Increment */ pBuffer++; /* Program the STOP */ I2C1->CR1 |= CR1_STOP_Set; /* Read DataN-1 */ *pBuffer = I2C1->DR; /* Re-enable IRQs */ __enable_irq(); /* Increment */ pBuffer++; /* Wait until RXNE is set (DR contains the last data) */ Timeout=0xFFFF; while ((I2C1->SR1 & 0x00040) != 0x000040) { if (Timeout-- == 0) return Error; } /* Read DataN */ *pBuffer = I2C1->DR; /* Reset the number of bytes to be read by master */ NumByteToRead = 0; } } /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */ Timeout=0xFFFF; while ((I2C1->CR1&0x200) == 0x200) { if (Timeout-- == 0) return Error; } /* Enable Acknowledgement to be ready for another reception */ I2C1->CR1 |= CR1_ACK_Set; Deal_I2CComming(); //MasterReceptionComplete=0x01; } #endif #if I2C_METHOD == INTERRUPT /* I2C1 Master Reception using Interrupts with highest priority in an application */ { /* Enable EVT IT*/ I2C1->CR2 |= I2C_IT_EVT; /* Enable BUF IT */ I2C1->CR2 |= I2C_IT_BUF; /* Set the I2C direction to reception */ I2CDirection = I2C_DIRECTION_RX; SlaveAddress |= OAR1_ADD0_Set; Address = SlaveAddress; NumbOfBytes = NumByteToRead; /* Send START condition */ I2C1->CR1 |= CR1_START_Set; /* Wait until the START condition is generated on the bus: START bit is cleared by hardware */ while ((I2C1->CR1&0x100) == 0x100); /* Wait until BUSY flag is reset (until a STOP is generated) */ while ((I2C1->SR2 &0x0002) == 0x0002); /* Enable Acknowledgement to be ready for another reception */ I2C1->CR1 |= CR1_ACK_Set; } #endif return Success; }
/******************************************************************************* * Function Name : MSD_ReadBlock * Description : Reads a block of data from the MSD. * Input : - pBuffer : pointer to the buffer that receives the data read * from the MSD. * - ReadAddr : MSD's internal address to read from. * - NumByteToRead : number of bytes to read from the MSD. * Output : None * Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed * - MSD_RESPONSE_NO_ERROR: Sequence succeed *******************************************************************************/ u8 MSD_ReadBlock_DMA(u8 *pBuffer, u32 ReadAddr, u16 NumByteToRead) { u8 rvalue = MSD_RESPONSE_FAILURE; DMA_InitTypeDef DMA_InitStructure; char DuumyClock[512]; // INT8U err; memset(DuumyClock, 0xff, 512); // debug("MSD_ReadBlock_DMA!\r\n"); if(CardInfo.CardType != CARDTYPE_SDV2HC) { ReadAddr = ReadAddr << 9; } /* MSD chip select low */ MSD_CS_LOW(); DMA_DeInit(DMA1_Channel4); DMA_DeInit(DMA1_Channel5); DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR; DMA_InitStructure.DMA_MemoryBaseAddr = (u32)pBuffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_BufferSize = 512; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel4, &DMA_InitStructure); DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DuumyClock; //512字节的dummy DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; //DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_Low; DMA_Init(DMA1_Channel5, &DMA_InitStructure); /* Enable DMA1 Channel4 Transfer Complete interrupt */ DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); /* Enable DMA1 Channel5 Transfer Complete interrupt */ DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE); SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE); /* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */ MSD_SendCmd(CMD17, ReadAddr, 0xFF); /* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */ if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR)) { /* Now look for the data token to signify the start of the data */ if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ)) { DMA_Cmd(DMA1_Channel5, ENABLE); DMA_Cmd(DMA1_Channel4, ENABLE); #ifdef DMA1_IRQ OSFlagPend(Sem_SD_DMA, (OS_FLAGS)3, OS_FLAG_WAIT_SET_ALL, 0, &err); //请求信号量集的第0和第1位且都置1。 //debug("MSD_ReadBlock_DMA OSFlagPend err=%d \r\n",err); DMA_ClearFlag(DMA1_FLAG_TC4); #else while(!DMA_GetFlagStatus(DMA1_FLAG_TC5)); while(!DMA_GetFlagStatus(DMA1_FLAG_TC4)); DMA_ClearFlag(DMA1_FLAG_TC4); #endif /* Get CRC bytes (not really needed by us, but required by MSD) */ MSD_ReadByte(); MSD_ReadByte(); /* Set response value to success */ rvalue = MSD_RESPONSE_NO_ERROR; } else { //debug("\r\n erro:MSD_START_DATA_SINGLE_BLOCK_READ\r\n"); } } else { //debug("\r\n error:MSD_RESPONSE_NO_ERROR\r\n"); } DMA_Cmd(DMA1_Channel4, DISABLE); DMA_Cmd(DMA1_Channel5, DISABLE); /* MSD chip select high */ MSD_CS_HIGH(); /* Send dummy byte: 8 Clock pulses of delay */ MSD_WriteByte(DUMMY_BYTE); /* Send stop data transmit command - CMD12 */ _send_command(CMD12, 0, 0); /* Returns the reponse */ return rvalue; }
/** * @brief Reads buffer of bytes from the slave. * @param pBuffer: Buffer of bytes to be read from the slave. * @param NumByteToRead: Number of bytes to be read by the Master. * @param Mode: Polling or DMA or Interrupt having the highest priority in the application. * @param SlaveAddress: The address of the slave to be addressed by the Master. * @retval : None. */ ErrorStatus I2C_Master_BufferRead(I2C_TypeDef* I2Cx, uint8_t* pBuffer, uint32_t NumByteToRead, I2C_ProgrammingModel Mode, uint8_t SlaveAddress, uint32_t timeoutMs) { __IO uint32_t temp = 0; __IO uint32_t Timeout = 0; /* Enable I2C errors interrupts (used in all modes: Polling, DMA and Interrupts */ I2Cx->CR2 |= I2C_IT_ERR; if (Mode == DMA) /* I2Cx Master Reception using DMA */ { /* Configure I2Cx DMA channel */ I2C_DMAConfig(I2Cx, pBuffer, NumByteToRead, I2C_DIRECTION_RX); /* Set Last bit to have a NACK on the last received byte */ I2Cx->CR2 |= CR2_LAST_Set; /* Enable I2C DMA requests */ I2Cx->CR2 |= CR2_DMAEN_Set; Timeout = 0xFFFF; /* Send START condition */ I2Cx->CR1 |= CR1_START_Set; /* Wait until SB flag is set: EV5 */ while ((I2Cx->SR1 & 0x0001) != 0x0001) { if (Timeout-- == 0) return ERROR; } Timeout = 0xFFFF; /* Send slave address */ /* Set the address bit0 for read */ SlaveAddress |= OAR1_ADD0_Set; Address = SlaveAddress; /* Send the slave address */ I2Cx->DR = Address; /* Wait until ADDR is set: EV6 */ while ((I2Cx->SR1 & 0x0002) != 0x0002) { if (Timeout-- == 0) return ERROR; } /* Clear ADDR flag by reading SR2 register */ temp = I2Cx->SR2; if (I2Cx == I2C1) { /* Wait until DMA end of transfer */ while (!DMA_GetFlagStatus(DMA1_FLAG_TC7)); //xSemaphoreTake(i2cdevDmaEventI2c1, M2T(timeoutMs)); /* Disable DMA Channel */ DMA_Cmd(I2C1_DMA_CHANNEL_RX, DISABLE); /* Clear the DMA Transfer Complete flag */ DMA_ClearFlag(DMA1_FLAG_TC7); } else /* I2Cx = I2C2*/ { /* Wait until DMA end of transfer */ while (!DMA_GetFlagStatus(DMA1_FLAG_TC5)); //xSemaphoreTake(i2cdevDmaEventI2c2, M2T(timeoutMs)); /* Disable DMA Channel */ DMA_Cmd(I2C2_DMA_CHANNEL_RX, DISABLE); /* Clear the DMA Transfer Complete flag */ DMA_ClearFlag(DMA1_FLAG_TC5); } /* Program the STOP */ I2Cx->CR1 |= CR1_STOP_Set; /* Make sure that the STOP bit is cleared by Hardware before CR1 write access */ while ((I2Cx->CR1 & 0x200) == 0x200) ; } /* I2Cx Master Reception using Interrupts with highest priority in an application */ else { /* Enable EVT IT*/ I2Cx->CR2 |= I2C_IT_EVT; /* Enable BUF IT */ I2Cx->CR2 |= I2C_IT_BUF; /* Set the I2C direction to reception */ I2CDirection = I2C_DIRECTION_RX; Buffer_Rx1 = pBuffer; SlaveAddress |= OAR1_ADD0_Set; Address = SlaveAddress; if (I2Cx == I2C1) NumbOfBytes1 = NumByteToRead; else NumbOfBytes2 = NumByteToRead; /* Send START condition */ I2Cx->CR1 |= CR1_START_Set; Timeout = timeoutMs * I2CDEV_LOOPS_PER_MS; /* Wait until the START condition is generated on the bus: START bit is cleared by hardware */ while ((I2Cx->CR1 & 0x100) == 0x100 && Timeout) { Timeout--; } /* Wait until BUSY flag is reset (until a STOP is generated) */ while ((I2Cx->SR2 & 0x0002) == 0x0002 && Timeout) { Timeout--; } /* Enable Acknowledgement to be ready for another reception */ I2Cx->CR1 |= CR1_ACK_Set; if (Timeout == 0) return ERROR; } return SUCCESS; temp++; //To avoid GCC warning! }
/** * @brief This function handles main Media layer interrupt. * @param None. * @retval o if correct communication, else wrong communication */ void Audio_MAL_IRQHandler(void) { #ifndef AUDIO_MAL_MODE_NORMAL uint16_t *pAddr = (uint16_t *)CurrentPos; uint32_t Size = AudioRemSize; #endif /* AUDIO_MAL_MODE_NORMAL */ #ifdef AUDIO_MAL_DMA_IT_TC_EN /* Transfer complete interrupt */ if (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC) != RESET) { #ifdef AUDIO_MAL_MODE_NORMAL /* Check if the end of file has been reached */ if (AudioRemSize > 0) { /* Wait the DMA Stream to be effectively disabled */ while (DMA_GetCmdStatus(AUDIO_MAL_DMA_STREAM) != DISABLE) {} /* Clear the Interrupt flag */ DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC); /* Re-Configure the buffer address and size */ DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) CurrentPos; DMA_InitStructure.DMA_BufferSize = (uint32_t) (DMA_MAX(AudioRemSize)); /* Configure the DMA Stream with the new parameters */ DMA_Init(AUDIO_MAL_DMA_STREAM, &DMA_InitStructure); /* Enable the I2S DMA Stream*/ DMA_Cmd(AUDIO_MAL_DMA_STREAM, ENABLE); /* Update the current pointer position */ CurrentPos += DMA_MAX(AudioRemSize); /* Update the remaining number of data to be played */ AudioRemSize -= DMA_MAX(AudioRemSize); } else { /* Disable the I2S DMA Stream*/ DMA_Cmd(AUDIO_MAL_DMA_STREAM, DISABLE); /* Clear the Interrupt flag */ DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC); /* Manage the remaining file size and new address offset: This function should be coded by user (its prototype is already declared in stm32_eval_audio_codec.h) */ EVAL_AUDIO_TransferComplete_CallBack((uint32_t)CurrentPos, 0); } #elif defined(AUDIO_MAL_MODE_CIRCULAR) /* Manage the remaining file size and new address offset: This function should be coded by user (its prototype is already declared in stm32_eval_audio_codec.h) */ EVAL_AUDIO_TransferComplete_CallBack(pAddr, Size); /* Clear the Interrupt flag */ DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TC); #endif /* AUDIO_MAL_MODE_NORMAL */ } #endif /* AUDIO_MAL_DMA_IT_TC_EN */ #ifdef AUDIO_MAL_DMA_IT_HT_EN /* Half Transfer complete interrupt */ if (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_HT) != RESET) { /* Manage the remaining file size and new address offset: This function should be coded by user (its prototype is already declared in stm32_eval_audio_codec.h) */ EVAL_AUDIO_HalfTransfer_CallBack((uint32_t)pAddr, Size); /* Clear the Interrupt flag */ DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_HT); } #endif /* AUDIO_MAL_DMA_IT_HT_EN */ #ifdef AUDIO_MAL_DMA_IT_TE_EN /* FIFO Error interrupt */ if ((DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TE) != RESET) || \ (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_FE) != RESET) || \ (DMA_GetFlagStatus(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_DME) != RESET)) { /* Manage the error generated on DMA FIFO: This function should be coded by user (its prototype is already declared in stm32_eval_audio_codec.h) */ EVAL_AUDIO_Error_CallBack((uint32_t*)&pAddr); /* Clear the Interrupt flag */ DMA_ClearFlag(AUDIO_MAL_DMA_STREAM, AUDIO_MAL_DMA_FLAG_TE | AUDIO_MAL_DMA_FLAG_FE | \ AUDIO_MAL_DMA_FLAG_DME); } #endif /* AUDIO_MAL_DMA_IT_TE_EN */ }