cancel
Showing results for 
Search instead for 
Did you mean: 

Problems with combining I/O devices on stm32f4discovery

Sietse
Associate III
Posted on March 12, 2014 at 13:20

      Dear List,

I have several problems with the use of multiple I/O devices at the same time.

I have a number of stm32f4discovery boards to test.

The software I use is build upon STM32_USB-Host-Device_Lib_V2.1.0, that I found on

     http://stm32.eeelec.com/html/STM32F4%20resources.htm

The software created is directly derived from the examples found in the resources mentioned.

I made it as simple as possible, no dma or interrupts, apart from the ucb-vcp device.

I have an application that uses: dac, adc, pwm, quadrature encoder, serial port, usb-vcp port.

If I only use a single device everything works perfectly, but if I start combining more devices

together problems start to arise.

There are no conflicts in the devices and pins used as far as I can see.

A few examples. The order in which devices are initialized matter. For example first initializing

the dac/adc and then the pwm/encoders behaves differently then the other way around.

Only one of the two situations works ok.

Another example is using both usb and usart2. Only using usb works ok, but if I also send data over the

usart2 mixed with the usb data, after a second or so everything freezes.

Before I send the source code, I have few questions.

Are there things to consider when using multiple devices? Something about the order of initializing?

How can mixing usb and usart data get me in trouble when both work perfectly separately?

    Thanks in advance, Sietse

#stm32f4
9 REPLIES 9
chen
Associate II
Posted on March 12, 2014 at 13:45

Hi

If the initialisstion code is written correctly - there should be no issue with initialisation order (at least in software - depends on the physical system).

Without seeing the code - cannot say what the issue is.

Guessing at what the problem might be?

IRQs all at the same level??

ISR interfering with each other.

frankmeyer9
Associate II
Posted on March 12, 2014 at 14:31

IRQs all at the same level??

 

ISR interfering with each other.

 

To be more exact, they probably block each other.

As a general hint, check if the peripheral unit provides an overflow flag, and examine it in your interrupt handler.

The data are lost then anyway, but you can deal with this situation, and it is really helpful in the debugging phase.

Andrew Neil
Evangelist
Posted on March 12, 2014 at 23:57

Obviously, if the hardware pin assignments conflict, then you're stuck.

There could be conflicting clock setups?

Accesses to shared registers not taking care to preserve the bits they shouldn't be modifying...

Sietse
Associate III
Posted on March 13, 2014 at 10:29

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6eH&d=%2Fa%2F0X0000000bsQ%2FQLH3RWD2xBsPJWVCOPgIyqlE1x98eU5maTK0bmjuvk0&asPdf=false
Sietse
Associate III
Posted on March 13, 2014 at 13:41

The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6eM&d=%2Fa%2F0X0000000bsS%2FSE6H6cXiCVOtz7Umwv4ItyqQO2bUyYgSnUyE9B8ggMU&asPdf=false
Sietse
Associate III
Posted on March 13, 2014 at 13:51

Dear list,

now that I found out how to format ;), I here repeat the code fragments from my first code post. Sietse Main.c :

#include <
stdio.h
>
#include <
stdlib.h
>
#include <
stdint.h
>
#include <
stdbool.h
>
#include <
math.h
>
#include <
errno.h
>
#include ''stm32f4xx.h''
#include ''stm32f4xx_conf.h''
#include ''stm32f4_discovery.h''
#include ''usbd_cdc_vcp.h''
#include ''usbd_cdc_core.h''
#include ''usbd_usr.h''
#include ''usb_conf.h''
#include ''usbd_desc.h''
#include ''fifo.h''
// fifo for usb
static uint8_t recdata[FIFO_SIZE];
fifo_t recfifo;
// structures used by more config functions.
GPIO_InitTypeDef GPIO_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
void usart2_config(void) {
USART_InitTypeDef USART_InitStructure;
/* enable peripheral clock for USART2 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
// USART2 form port PD
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
// USART2 TX
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* GPIOA Configuration: USART2: CTS, RTS, RX on PD3, PD4, PD6 */
// TX on PD5 is not possible, used for USB-OTG overcurrent.
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 |GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOD, &GPIO_InitStructure);
// TX op PA2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Connect USART2 pins to AF2 */
GPIO_PinAFConfig(GPIOD, GPIO_PinSource3, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_USART2);
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_HardwareFlowControl = USART_HardwareFlowControl_RTS_CTS;
USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
USART_Init(USART2, &USART_InitStructure);
USART_Cmd(USART2, ENABLE); // enable USART2
}
__ALIGN_BEGIN USB_OTG_CORE_HANDLE USB_OTG_dev __ALIGN_END ;
void usb_init(void) {
USBD_Init(&USB_OTG_dev,
#ifdef USE_USB_OTG_HS 
USB_OTG_HS_CORE_ID,
#else 
USB_OTG_FS_CORE_ID,
#endif 
&USR_desc, 
&USBD_CDC_cb, 
&USR_cb);
}
void targettest_comm(void)
{
int i, j, k, length;
char c;
size_t sizeRecv, sizeSend;
char tekst[20];
// first READ a string from usb to synchronize,
k = 10000000;
while ((k--)>0) {
length = 10;
i = 0;
while (i< length) {
j = rtIOStreamRecv(1,tekst+i, length-i, &sizeRecv);
i += j;
}
tekst[length]=0;
i = 0;
while (i < length) {
j = rtIOStreamSend(1,tekst+i,length-i,&sizeSend);
i += j;
}
GPIO_ToggleBits(LED_GREEN_GPIO_PORT, LED_GREEN_PIN);
// clear buffer
j=0;
while (j<32) {
tekst[j]=0;
j++;
}
// delay(k%10);
}
}
int main(void)
{
usart2_config();
printf(''Start

'');
fifo_init(&recfifo, recdata);
usb_init();
printf(''Usb started

'');
targettest_comm();
return 0;
}

Fragment syscalls.c :

int _write(int file, char *ptr, int len) {
int l=len; volatile char *s=ptr;
while(l>0){
// wait until data register is empty
// waarom niet TXE ipv TC ?
while( !(USART2->SR & 0x00000040) );
USART_SendData(USART2, *s);
*s++;l--;
}
return 0;
}

Fragment rtiostream_serial_stm32f4.c :

// blocking
int rtIOStreamSend(
int streamID,
const void *src,
size_t size,
size_t *sizeSent) {
static int telint;
int i;
// test streamID?
VCP_DataTx((uint8_t *)src, size);
// debug
// if (telint > 1000) {
if (size) {
char c;
iprintf(''Sending %d bytes: '', size);
for (i = 0; i<
size
; i++) {
c=((char *)src)[i];
iprintf('' %x '',c);
}
iprintf(''

'');
}
// }
telint++;
// delay(5);
*
sizeSent
= size;
return size;
}
int 
pollm
= 
1
;
// non-blocking
int rtIOStreamRecv(
int streamID,
void * dst, 
size_t size,
size_t * sizeRecvd) {
static int recint;
int i; uint8_t c; uint32_t j;
if (size == 0) {
*
sizeRecvd
= 
0
;
return 0;
}
else 
if ((
i
=
fifo_avail
(&recfifo))) {
if (i > size) i = size;
for ( j=0; j<
i
; j++) {
if (fifo_get(&recfifo,&c)) {
((char *)dst)[j] = c;
}
}
pollm
= 
1
;
// if (recint > 1000) {
// debug 
if (i) {
iprintf(''Received %d byte of total %d: '', i, size);
for (j = 0; j<i; j++) {
c=((char *)dst)[j];
iprintf(''%x '',c);
// if (c==0x5e)
// iprintf(''Should not happen!

'');
} 
iprintf(''

'');
}
// }
recint++;
// delay(5);
*sizeRecvd = i;
return i;
} else {
if (pollm) {
// iprintf(''polling

'');
pollm =0;
}
return 0;
}
}

Fragment usbd_cdc_vpc.c :

static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len)
{
int i = Len; int j;
if (i > fifo_free(&recfifo)) {
// fifo full (fail of weggooien? cannot happen?)
return USBD_FAIL;
}
else {
j = 0;
while (j<i) {
fifo_put(&recfifo,Buf[j]);
if (running) {
testbuf[testind++]=Buf[j];
if (testind == 2000) {
running = 0;
teller++;
testind=0;
}
}
j++;
}
}
return USBD_OK;
}

Sietse
Associate III
Posted on March 13, 2014 at 14:03

I forgot to mention what goes wrong with the dac/adc encoder/pwm example.
 All is well if dac/adc is initialised first.
 But is we first initialize encoder/pwm, then the DAC works, but the ADC always
 returns zero.
 Sietse

Sietse
Associate III
Posted on March 14, 2014 at 14:05

The dac/adc and timer/encoder problem seems to have vanished....

It now is working perfectly. Strange.

I leave it at that, and now focus on the usart/usb problem, that still occurs.

Hopefully someone can give me a hint.

   Sietse

Sietse
Associate III
Posted on March 14, 2014 at 14:40

OK, i'm a step ahead!

It has nothing to do with the usart I think.

 1.  The printf's in the usb-receive do not matter. It always works.

 2.  The problem is combining with the usb-send routine.

 3.   If I remove all printf's, and put a delay-loop of 0.1 sec of longer in the usb-send routine,

        the problem occurs. It freezes at exactly the same problem.

This is even stranger, why can I only do

      VCP_DataTx((uint8_t *)src, size)

function calls without too long delay's  in between?

   Sietse