cancel
Showing results for 
Search instead for 
Did you mean: 

UART_Printf example on OS X, problems with USB-serial

Sebastian Gniazdowski
Associate III
Posted on January 26, 2017 at 17:04

UART_Printf example (Nucle-F767ZI, 144 pins) works correctly, I get printf output on OS X, using Zterm (PC HyperTerminal replacement).

However mouse is locked when I connect with Zterm and start listening. Computer is thus barely usable, I have to revert to keyboard-mouse accessibility feature (mouse mapped to numerical keys). The same happens with Coolterm, so this is not Zterm specific. Below is the USB-serial device that Zterm selects:

0690X000006069NQAQ.png

Mouse must be in the same ''channel'' with STM32 in usbmodemFA133. Can ST provide support on this? How to add additional ''usbmodemFAxxx'' driver, separate for STM32 board (Nucleo-F767ZI) ? Internet is blank at this. I think many users can have similar issue.

#freeze #hyperterminal #uart #usb #printf-hal_uart_transmit #os-x #printf
3 REPLIES 3
john doe
Lead
Posted on January 26, 2017 at 19:46

you dont need zterm or anything. from the shell prompt you can simply

$ screen /dev/tty.usbmodemXXXXXX 115200

your problem is a zterm problem or install problem not a serial port driver problem or stm32 problem.

Posted on January 26, 2017 at 23:32

I've did:

screen /dev/tty.usbmodemFA133 9600

and it's the same – mouse is blocked. I kindly ask to include this generic problem in ST support, so that STM32 can print to UART.

Posted on January 27, 2017 at 00:01

That's good, it didn't sound reasonable.  I am currently working on USB UARTs and just got it working.

My code was generated by cube for the STM32F407G-DISC1 board, so you can regen it for yours (if you wish). All I did was turn on the USB device, device FS, for CDC. Gen the code and then I put in the interface routines for GCC/newlib to use printf/scanf via USB. 

Attached is main.c and the support file that has to be munged.

...and the widget to attach a file is gone... what the hell ST????

Sorry about the formatting, I tried but these tools suck.

main.c

...

int

main(

void

)

{

 

/* USER CODE BEGIN 1 */

/*

* a test program to see what it takes to get a USB

com

port working.

*

* To get the I/O to work, I put in the helpers to get stdio to work. This means

* _read and _write.

*

* The USB portion is handled by the code in usbd_cdc_if.c. All of the action happens there.

* Actually, the interface is pretty weird. The only public function is CDC_Transmit_FS. That means

* that there is no access to CDC_Receive_FS externally.

Wuh

?

*

* The unwritten interface is that you are supposed to

munge

usbd_cdc_if.c to be able to get at the read

* and write routines. So I placed _write in there, which calls CDC_Transmit_FS.

*

* _read is handled a little different. CDC_Receive_FS is a callback routine that is called by the USB stack

* once some data has been received. I ended up putting some code in there to dequeue the USB data and dump

* it into a secondary buffer. Once

getchar

/

scanf

/??? is called, _read will then go and attack the secondary

* buffer. Of course, _read only returns once the buffering is satisfied, so main calls

setvbuf

to clobber the

* stdio buffering.

*

* Since _read is blocking, I also threw in

kbhit

() to free up the processor.

*/

char

ch;

 

/* USER CODE END 1 */

 

/* MCU Configuration----------------------------------------------------------*/

 

/* Reset of all peripherals, Initializes the Flash interface and the

Systick

. */

 

HAL_Init();

 

/* Configure the system clock */

 

SystemClock_Config();

 

/* Initialize all configured peripherals */

 

MX_GPIO_Init();

 

MX_USB_DEVICE_Init();

 

/* USER CODE BEGIN 2 */

 

setvbuf

(stdin, NULL, _IONBF, 0);

 

/* USER CODE END 2 */

 

/* Infinite loop */

 

/* USER CODE BEGIN WHILE */

while

(1) {

 

/* USER CODE END WHILE */

 

/* USER CODE BEGIN 3 */

if

(kbhit()) {

ch = getchar();

putchar(ch);

}

HAL_Delay(1);

}

 

/* USER CODE END 3 */

}

usbd_cdc_if.c:

/**

 

* @brief

 

CDC_Receive_FS

 

*

       

Data received over USB OUT

endpoint

are sent over CDC interface

 

*

       

through this function.

 

*

           

 

*

       

@note

 

*

       

This function will block any OUT packet reception on USB

endpoint

 

*

       

untill

exiting this function. If you exit this function before transfer

 

*

       

is complete on CDC interface (

ie

. using DMA controller) it will result

 

*

       

in receiving more data while previous ones are still not sent.

 

*

                 

 

* @

param

 

Buf

: Buffer of data to be received

 

* @

param

 

Len

: Number of data received (in bytes)

 

* @

retval

Result of the operation: USBD_OK if all operations are OK else USBD_FAIL

 

*/

static

int8_t

CDC_Receive_FS (

uint8_t

* Buf,

uint32_t

*Len)

{

 

/* USER CODE BEGIN 6 */

 

USBD_CDC_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);

 

USBD_CDC_ReceivePacket(&hUsbDeviceFS);

 

receivedLen = *Len;

 

memcpy

( &receivedData[totalReceived], Buf, receivedLen);

 

totalReceived += receivedLen;

 

return

(

USBD_OK

);

 

/* USER CODE END 6 */

}

/**

 

* @brief

 

CDC_Transmit_FS

 

*

       

Data send over USB IN

endpoint

are sent over CDC interface

 

*

       

through this function.

           

 

*

       

@note

 

*

         

 

*

                 

 

* @

param

 

Buf

: Buffer of data to be send

 

* @

param

 

Len

: Number of data to be send (in bytes)

 

* @

retval

Result of the operation: USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY

 

*/

uint8_t

CDC_Transmit_FS(

uint8_t

* Buf,

uint16_t

Len)

{

 

uint8_t

result =

USBD_OK

;

 

/* USER CODE BEGIN 7 */

 

USBD_CDC_HandleTypeDef

*hcdc = (

USBD_CDC_HandleTypeDef

*)hUsbDeviceFS.

pClassData

;

 

if

(hcdc->

TxState

!= 0){

   

return

USBD_BUSY

;

 

}

 

USBD_CDC_SetTxBuffer(&hUsbDeviceFS, Buf, Len);

 

result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);

 

/* USER CODE END 7 */

 

return

result;

}

/* USER CODE BEGIN PRIVATE_FUNCTIONS_IMPLEMENTATION */

/**

 

* @}

 

*/

int

_write(

int

file,

char

*outgoing,

int

len) {

if

(hUsbDeviceFS.

dev_state

== USBD_STATE_CONFIGURED){

CDC_Transmit_FS( outgoing, len);

}

  

return

len;

}

/**

 

* @}

 

*/

int

_read(

int

file,

char

* result,

size_t

len) {

if

(len == 0) {

return

(0);

}

while

(totalReceived < len) {

HAL_Delay(10);

}

memcpy

( result, receivedData, len);

totalReceived = 0;

return

(len);

}

/**

 

* @}

 

*/

bool kbhit(

void

) {

return

(totalReceived > 0);

}