STM32F3 I2C read data - embedded

I'm using the STM32F373 microcontroller and wrote a simple function to read data from a MPU6050 gyro+accel on i2c 1 (PB7 PB6).
The problem is that when I try to read sensor register data - flag I2C_ISR_TXIS is always equal to RESET (not set).
Why might this happen?
Here is some source code that demonstrates the problem.
void i2c1_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
I2C_InitTypeDef I2C_InitStructure;
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_4);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_4);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);
I2C_DeInit(I2C1);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStructure.I2C_DigitalFilter = 0x00;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStructure.I2C_Timing = 0xC062121F;
I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE);
}
uint8_t i2c_read(uint8_t DeviceAddr, uint8_t RegAddr, uint8_t* pBuffer, uint16_t len)
{
/* Test on BUSY Flag */
uint32_t timeout = I2C_TIMEOUT;
while(I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET)
{
if((timeout--) == 0) return 0;
}
I2C_TransferHandling(I2C1, DeviceAddr, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
/* !!! Wait until TXIS flag is set !!! */
timeout = I2C_TIMEOUT;
while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET) // PROBLEM HERE!!!!!!!!!!!!!!!
{
if((timeout--) == 0) return 0;
}
....
....
}

OK,I found the problem. Flag I2C_ISR_TXIS did not get because the device on the i2c did not respond to the sent address. Need to convert the device address to 7 bits.
(DeviceAddr & 0x7f) << 1

Related

why this code using dspic33ep512mu810 chip uart 2 not working

In MPLAB X IDE v5.10, I am using dspic33ep512mu810 microcontroller.
I have following piece of C code:
#include "xc.h"
_FOSCSEL(FNOSC_FRCPLL) //INT OSC with PLL (always keep this setting)
_FOSC(OSCIOFNC_OFF & POSCMD_NONE) //disable external OSC
_FWDT(FWDTEN_OFF) //watchdog timer off
_FICD(JTAGEN_OFF & 0b11); //JTAG debugging off
void UART2TX(char c) {
if (U2STAbits.UTXEN == 0)
U2STAbits.UTXEN = 1; //enable UART TX
while (U2STAbits.UTXBF == 1); //if buffer is full, wait
U2TXREG = c;
}
int main(void) {
//setup internal clock for 80MHz/40MIPS
//7.37/2=3.685*43=158.455/2=79.2275
CLKDIVbits.PLLPRE = 0; // PLLPRE (N2) 0=/2
PLLFBD = 41; //pll multiplier (M) = +2
CLKDIVbits.PLLPOST = 0; // PLLPOST (N1) 0=/2
while (!OSCCONbits.LOCK); //wait for PLL ready
_U2TXIF = 0;
_U2TXIE = 0;
_U2RXIF = 0;
_U2RXIE = 0;
//setup UART
U2BRG = 85; //86#80mhz, 85#79.xxx=115200
U2MODE = 0; //clear mode register
U2MODEbits.BRGH = 1; //use high percison baud generator
U2STA = 0; //clear status register
//DSPIC33EP512MU810T-I/PT, RP96 as TX pin
RPOR7bits.RP96R = 3; //
while (1) {
UART2TX('H');
}
}
I am trying to send out 'H' through UART2 with baud rate 115200, but it is not working.
You had to switch RF0 (RP96) aus output:
TRISFbits.TRISF0 = 0; //make F0 an onput
And you had to switch RFO to digital:
ANSELFbits.ANSF0 = 0; //make F0 digital

STM32F4329II Input capture Interrupt ignored

STM32F4329II Input capture Interrupt is ignored while trying to use the input capture
 
static void TIM_Config(void)
{
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //GPIO_PuPd_NOPULL;
GPIO_PinAFConfig(GPIOH, GPIO_PinSource11, GPIO_AF_TIM5);
GPIO_Init(GPIOH, &GPIO_InitStructure);
/* TIM5 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
TIM_ICInitTypeDef TIM_InputCaptureInitStructure;
TIM_InputCaptureInitStructure.TIM_Channel = TIM_Channel_2;
TIM_InputCaptureInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
TIM_InputCaptureInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_InputCaptureInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
TIM_InputCaptureInitStructure.TIM_ICFilter = 0x0;
TIM_ICInit(TIM5, &TIM_InputCaptureInitStructure);
TIM_ClearFlag(TIM5, TIM_FLAG_CC2 );
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //
NVIC_Init(&NVIC_InitStructure);
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
//Enable CC2 interrupt
TIM_ITConfig(TIM5,TIM_IT_CC2,ENABLE);
//EnableTIM5
TIM_Cmd(TIM5,ENABLE);
}
And the following IRQ
extern "C" void TIM5_IRQHandler(void)
{
if (TIM_GetITStatus(TIM5, TIM_IT_CC2) == SET)
{
TIM_ClearITPendingBit(TIM5, TIM_IT_CC2);
rpm4 = TIM_GetCapture2(TIM5);
static char xx[12];
sprintf( xx, " %l", rpm4 );
GUI_DispStringAt(xx,100,150);
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC2 );
}
I put some breakpoints inside the Interrupt routine but nothing happens...
My external signal is a 5V signal ( this micro is 5V tolerant... ) with negative pulses...

Stm32f407IG SPI communication

#include <stm32f4xx.h>
#include "stm32f4xx_spi.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_rcc.h"
#include "config.h"
void init_GPIO()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOI,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOI , &GPIO_InitStructure);
}
void SPI1_Configuration_master(void)
{
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(Open_SPI1_SCK_GPIO_CLK | Open_SPI1_MISO_GPIO_CLK | Open_SPI1_MOSI_GPIO_CLK |Open_SPI1_NSS_GPIO_CLK ,ENABLE);
RCC_APB2PeriphClockCmd(Open_RCC_APB2Periph_SPI1,ENABLE);
GPIO_PinAFConfig(Open_SPI1_SCK_GPIO_PORT, Open_SPI1_SCK_SOURCE, Open_SPI1_MOSI_AF);
GPIO_PinAFConfig(Open_SPI1_MISO_GPIO_PORT, Open_SPI1_MISO_SOURCE, Open_SPI1_MOSI_AF);
GPIO_PinAFConfig(Open_SPI1_MOSI_GPIO_PORT, Open_SPI1_MOSI_SOURCE, Open_SPI1_MOSI_AF);
GPIO_PinAFConfig(Open_SPI1_NSS_GPIO_PORT, Open_SPI1_NSS_SOURCE, Open_SPI1_NSS_AF);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_SCK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(Open_SPI1_SCK_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_MISO_PIN;
GPIO_Init(Open_SPI1_MISO_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_MOSI_PIN;
GPIO_Init(Open_SPI1_MOSI_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI1_NSS_PIN;
GPIO_Init(Open_SPI1_NSS_GPIO_PORT, &GPIO_InitStructure);
SPI_I2S_DeInit(Open_SPI1);
SPI_InitStruct.SPI_Direction= SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft ;
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_CRCPolynomial = 7;
SPI_Init(Open_SPI1, &SPI_InitStruct);
SPI_Cmd(Open_SPI1, ENABLE);
}
void SPI_Configuration2_slave(void)
{
SPI_InitTypeDef SPI_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(Open_SPI2_SCK_GPIO_CLK | Open_SPI2_MISO_GPIO_CLK | Open_SPI2_MOSI_GPIO_CLK| Open_SPI2_NSS_GPIO_CLK,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
GPIO_PinAFConfig(Open_SPI2_SCK_GPIO_PORT, Open_SPI2_SCK_SOURCE, Open_SPI2_MOSI_AF);
GPIO_PinAFConfig(Open_SPI2_MISO_GPIO_PORT, Open_SPI2_MISO_SOURCE, Open_SPI2_MOSI_AF);
GPIO_PinAFConfig(Open_SPI2_MOSI_GPIO_PORT, Open_SPI2_MOSI_SOURCE, Open_SPI2_MOSI_AF);
GPIO_PinAFConfig(Open_SPI2_MOSI_GPIO_PORT, Open_SPI2_NSS_SOURCE, Open_SPI2_MOSI_AF);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_SCK_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_Init(Open_SPI2_SCK_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_MISO_PIN;
GPIO_Init(Open_SPI2_MISO_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_MOSI_PIN;
GPIO_Init(Open_SPI2_MOSI_GPIO_PORT, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = Open_SPI2_NSS_PIN;
GPIO_Init(Open_SPI2_MOSI_GPIO_PORT, &GPIO_InitStructure);
SPI_I2S_DeInit(Open_SPI2);
SPI_InitStruct.SPI_Direction= SPI_Direction_2Lines_FullDuplex;
SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStruct.SPI_Mode = SPI_Mode_Slave;
SPI_InitStruct.SPI_CPOL = SPI_CPOL_High;
SPI_InitStruct.SPI_CPHA = SPI_CPHA_2Edge;
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft ;
//SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStruct.SPI_CRCPolynomial = 7;
SPI_Init(Open_SPI2, &SPI_InitStruct);
SPI_Cmd(Open_SPI2, ENABLE);
}
u16 SPI2_Send_byte(u16 data)
{
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI2,data);
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open_SPI2);
}
u16 SPI2_Receive_byte(void)
{/*
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI2,0x00);
*/
while(SPI_I2S_GetFlagStatus(Open_SPI2, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open_SPI2);
}
u16 SPI_Send_byte(u16 data)
{
GPIO_ResetBits(GPIOI,GPIO_Pin_10);
while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI1,data);
while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_RXNE)==RESET);
GPIO_SetBits(GPIOI,GPIO_Pin_10);
return SPI_I2S_ReceiveData(Open_SPI1);
}
u16 SPI_Receive_byte(u16 data)
{
/*while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open_SPI1,data);
*/
while(SPI_I2S_GetFlagStatus(Open_SPI1, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open_SPI1);
}
int main()
{
char a;
init_GPIO();
SPI_Configuration2_slave();
SPI1_Configuration_master();
GPIO_SetBits(GPIOI,GPIO_Pin_10);
while(1)
{
a =SPI_Send_byte((u16)'a');
a = SPI2_Receive_byte();
}
return 0;
}
I am trying to implement Spi on STM32F407ig
I am currently trying to implement communication between two Spi1 and SPI2 on the same board.
I tried the similar code for communication between boards.
when i loop back mosi and miso of master i get the data transmitted.
but the slave does not receive any thing or it receives zero.
The connections made are right.
also the Macros used like Open_SPI1 are right.
I want to know if my configuration of SPI master and slave is right.
Could someone also elaborate on how the NSS software exactly work.
I had an issue with SPI on STM32F2 series. I had to toggle the NSS line manually and everything worked fine after that. Not sure if F4 has the same problem (maybe it's even by design). Here's my code:
/******************************************************************************/
void SPI_GPIO_init( void )
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure SPI pins SCK and MOSI to be hardware controlled */
GPIO_InitStructure.GPIO_Pin = SPI_PIN_SCK | SPI_PIN_MOSI;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init( SPI_GPIO_PORT, &GPIO_InitStructure );
/* Configure SPI pin MISO to be an input pin since we are master */
GPIO_InitStructure.GPIO_Pin = SPI_PIN_MISO;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init( SPI_GPIO_PORT, &GPIO_InitStructure );
/* Configure SPI pin NSS to be a regular GPIO output. This is due to STM32
* goofy handling of SPI: NSS stays low for the entire duration of SPI being
* enabled instead of being released after outgoing data is completed. This
* is basically a HW bug but it definitely mentiones this in the Ref Manual.
*
* From the reference manual RM0090:
* - NSS output enabled (SSM = 0, SSOE = 1)
* This configuration is used only when the device operates in master mode.
* The NSS signal is driven low when the master starts the communication and
* is kept low until the SPI is disabled.
*
* Instead, we are going to drive this pin manually as CLRC663 chip expects
* */
GPIO_InitStructure.GPIO_Pin = SPI_PIN_NSS;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( SPI_GPIO_PORT, &GPIO_InitStructure );
SPI_NSS_high();
DelayMS(1);
}
/******************************************************************************/
void SPI_NSS_high( void )
{
GPIO_WriteBit( SPI_GPIO_PORT, SPI_PIN_NSS, Bit_SET);
}
/******************************************************************************/
void SPI_NSS_low( void )
{
GPIO_WriteBit( SPI_GPIO_PORT, SPI_PIN_NSS, Bit_RESET);
}
/******************************************************************************/
void SPI_init( void )
{
SPI_I2S_DeInit( SPI1 );
SPI_NSS_high();
SPI_InitTypeDef SPI_InitStructure;
/* SPI1 configuration */
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 0;
SPI_Init( SPI1, &SPI_InitStructure );
SPI_Cmd( SPI1, ENABLE );
/* Not using interrupts for SPI communication so don't enable the NVIC and
* the ISR for it.*/
}
/******************************************************************************/
Error SPI_send( uint8_t *snd_buf, uint8_t snd_buf_len )
{
uint8_t snd_indx = 0;
uint8_t spi_retry = 0;
SPI_NSS_low(); /* Assert the NSS pin low to become SPI bus master */
for ( snd_indx = 0; snd_indx < snd_buf_len; snd_indx++ )
{
/* When SPI Tx buffer is empty, send data. Make sure we don't get
* stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to send data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
SPI_I2S_SendData( SPI1, snd_buf[ snd_indx ] );
// debug_printf("Sent %02x\n", snd_buf[ snd_indx ]);
/* Get the dummy byte coming back when SPI Rx buffer is empty. Make sure
* we don't get stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_RXNE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to receive data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
SPI_I2S_ReceiveData( SPI1 ); /* Dummy byte so no need to store it */
}
SPI_NSS_high(); /* Assert the NSS pin high to release SPI bus master */
return ( ERR_NONE );
}
/******************************************************************************/
Error SPI_transceive(
uint8_t *snd_buf,
uint8_t snd_buf_len,
uint8_t *rcv_buf,
uint8_t rcv_buf_len
)
{
uint8_t snd_indx = 0;
uint8_t rcv_indx = 0;
uint16_t spi_retry = 0;
SPI_NSS_low(); /* Assert the NSS pin low to become SPI bus master */
if ( snd_buf_len != rcv_buf_len )
{
err_printf("SPI expects to receive same amount of data that it is sending\n");
return ( ERR_HW_SPI_LENGTH_MISMATCH );
}
for ( snd_indx = 0; snd_indx < snd_buf_len; snd_indx++, rcv_indx++ )
{
/* When SPI Tx buffer is empty, send data. Make sure we don't get
* stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_TXE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to send data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
SPI_I2S_SendData( SPI1, snd_buf[ snd_indx ] );
/* Now receive the reply when the Rx buffer is empty. Make sure we don't
* get stuck in an inf loop while waiting for HW */
spi_retry = 0;
while ( SET != SPI_I2S_GetFlagStatus( SPI1, SPI_I2S_FLAG_RXNE ) )
{
if ( 0xFF == spi_retry++ )
{
err_printf("Reached SPI hardware retries trying to receive data over SPI bus\n");
return ( ERR_HW_SPI_TIMEOUT );
}
}
uint8_t data = SPI_I2S_ReceiveData( SPI1 );
rcv_buf[ rcv_indx ] = data;
// debug_printf("Got %02x\n", data );
}
SPI_NSS_high(); /* Assert the NSS pin high to release SPI bus master */
return ( ERR_NONE );
}

I'm looking for sample code to service the USCI (UART) on an MSP430 via DMA not interrupts

I have code that works "ok" for reading the USCI (UART) via interrupts, but the TI SimpliciTI stack is a CPU hog and it drops UART bytes when servicing the radio.
I assume DMA is the way to go, but I couldn't find a full example of DMA using USCI as input.
Here's what I ended up doing. It works!
struct {
#ifndef USE_DMA
volatile uint8_t rx_head ;
#endif
volatile uint8_t rx_tail ;
uint8_t rx_buffer[128];
} uart = { 0,0};
void UART_Init(void)
{
#ifndef USE_DMA
uart.rx_head = 0;
#endif
uart.rx_tail = 0;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
PMAPPWD = 0x02D52; // Get write-access to port mapping regs
P1MAP5 = PM_UCA0RXD; // Map UCA0RXD output to P1.5
P1MAP6 = PM_UCA0TXD; // Map UCA0TXD output to P1.6
PMAPPWD = 0; // Lock port mapping registers
P1DIR |= BIT6; // Set P1.6 as TX output
P1SEL |= BIT5 + BIT6; // Select P1.5 & P1.6 to UART function
UCA0CTL1 = UCSWRST; // **Put state machine in reset**
#ifdef UART_9600
UCA0CTL1 |= UCSSEL_1; // CLK = ACLK
UCA0BR0 = 0x03; // 32kHz/9600=3.41 (see User's Guide)
UCA0BR1 = 0x00; //
UCA0MCTL = UCBRS_3+UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
#elif defined(UART_9600_SMCLK)
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 0xE2; // 12MHz/12500
UCA0BR1 = 0x04; //
UCA0MCTL = UCBRS_2+UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
#elif defined(UART_115200)
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 104; // 12MHz/115200
UCA0BR1 = 0; //
UCA0MCTL = UCBRS_1 + UCBRF_0; // Modulation UCBRSx=1, UCBRFx=0
#else
#error Please select one of the supported baudrates.
#endif
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
#ifdef USE_DMA
memset(uart.rx_buffer,0,sizeof(uart.rx_buffer));
DMACTL0 = DMA0TSEL_16; // USCIA0 RX trigger
DMA0SAL = (uint16_t) &UCA0RXBUF; // Source address
DMA0DAL = (uint16_t) uart.rx_buffer; // Destination address
DMA0SZ = sizeof(uart.rx_buffer); // Block size. this counts down to 0, then reloads.
DMA0CTL = DMADSTINCR_3 + DMASBDB + DMADT_4 + DMALEVEL;
DMA0CTL |= DMAEN;
#else
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
#endif
}
int UART_GetChar(void)
{
#ifdef USE_DMA
if (DMA0SZ + uart.rx_tail != sizeof(uart.rx_buffer))
#else
if ( uart.rx_head != uart.rx_tail )
#endif
{
int c;
c = uart.rx_buffer[uart.rx_tail];
uint8_t next = uart.rx_tail + 1;
if (next >= sizeof(uart.rx_buffer)) next = 0;
uart.rx_tail = next;
return c;
}
return -1;
}

pic18f45550 usb problem

I am trying to build a very simple USB communication device using pic 18f4550
with default mikroelectronica example with no change (only change with hardware that I don't have couple of 100nf attached with vusb so I replaced them with 470uf
and I didn't put any pf with my crystal oscillator)
The hardware:
The code is working very will with Proteus simulation:
unsigned char k;
unsigned char userWR_buffer[64];
const char *text = "MIKROElektronika Compilers ER \r\n";
//**************************************************************************************************
// Main Interrupt Routine
//**************************************************************************************************
void interrupt()
{
HID_InterruptProc();
}
//**************************************************************************************************
//**************************************************************************************************
// Initialization Routine
//**************************************************************************************************
void Init_Main()
{
//--------------------------------------
// Disable all interrupts
//--------------------------------------
INTCON = 0; // Disable GIE, PEIE, TMR0IE,INT0IE,RBIE
INTCON2 = 0xF5;
INTCON3 = 0xC0;
RCON.IPEN = 0; // Disable Priority Levels on interrupts
PIE1 = 0;
PIE2 = 0;
PIR1 = 0;
PIR2 = 0;
ADCON1 |= 0x0F; // Configure all ports with analog function as digital
CMCON |= 7; // Disable comparators
//--------------------------------------
// Ports Configuration
//--------------------------------------
TRISA = 0xFF;
TRISB = 0xFF;
TRISC = 0xFF;
TRISD = 0;
TRISE = 0x07;
LATA = 0;
LATB = 0;
LATC = 0;
LATD = 0;
LATE = 0;
//--------------------------------------
// Clear user RAM
// Banks [00 .. 07] ( 8 x 256 = 2048 Bytes )
//--------------------------------------
}
//**************************************************************************************************
//**************************************************************************************************
// Main Program Routine
//**************************************************************************************************
void main() {
char i;
Init_Main();
HID_Enable(&userWR_buffer, &userWR_buffer);
Delay_ms(1000);
Delay_ms(1000);
while(1) {
Delay_ms(1000);
i=0;
while(text[i]) {
userWR_buffer[0]= text[i++];
while (!HID_Write(&userWR_buffer, 1));
}
}
Delay_ms(1000);
HID_Disable();
}
//**************************************************************************************************
I didn't put any pf with my crystal oscillator
I don't think this will work. Check with an oscilloscope what happens on your crystal. Your device has simply no clock input so it never executes anything.