2014-03-12 05:20 AM
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 #stm32f42014-03-12 05:45 AM
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.2014-03-12 06:31 AM
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.
2014-03-12 03:57 PM
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...2014-03-13 02:29 AM
2014-03-13 05:41 AM
2014-03-13 05:51 AM
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;
}
2014-03-13 06:03 AM
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
2014-03-14 06:05 AM
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. Sietse2014-03-14 06:40 AM
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