Luca Gotti

Other "small" bug in TWRK60 BSP ( MQX 3.7 )

Discussion created by Luca Gotti on Jun 10, 2011
Latest reply on Sep 19, 2011 by Staffan Solen

Recently i've tried to use a UART ( UART4 in the specific ) at a baud rate greater than 230400 ( llike 460800 or 921600 ) , and i see that i couldn't communicate with the host ( the GS1011M Wifi module in my specific case ) .

The reason is quite simple :  the function _kuart_polled_ioctl() in file mqx\source\io\serial\polled\serl_pol_kuart.c, modify only the baud rate registers ( BDH and BDL ) but at such high speed the error can be greater than 6 % !!

The solution is to set the BRFA ( Baud Rate Fine Adjust ) filed in register UART_C4 ; in this way i could get an error of  less 0.2 % and be able to tals correctly with my host .

For those interested to the code , this is the orignal "wrong" code (from line 345 ) :

 

     case IO_IOCTL_SERIAL_SET_BAUD:
         /* baud_divisor = clock_speed / baudrate + 0.5 */ 
         baud = (io_info_ptr->INIT.CLOCK_SPEED + (8 * (*param_ptr))) / (16 * (*param_ptr));
         if (baud > (UART_BDH_SBR_MASK << 8))
             return IO_ERROR_INVALID_IOCTL_CMD;
         io_info_ptr->INIT.BAUD_RATE = *param_ptr;   
         sci_ptr->BDH = (uchar)((baud >> 8) & UART_BDH_SBR_MASK);
         sci_ptr->BDL = (uchar)(baud & UART_BDL_SBR_MASK);     
         break;

I've modified in this way :

     case IO_IOCTL_SERIAL_SET_BAUD:
         /* baud_divisor = clock_speed / baudrate + 0.5 */ 
         baud = (io_info_ptr->INIT.CLOCK_SPEED + (8 * (*param_ptr))) / (16 * (*param_ptr));
         if (baud > (UART_BDH_SBR_MASK << 8))
             return IO_ERROR_INVALID_IOCTL_CMD;
         io_info_ptr->INIT.BAUD_RATE = *param_ptr;   

        /* Added this  code for high baud rates ... */
         switch ( *param_ptr ) {
            case 460800UL:
                baud = 6;       // Baud Rate = 48000000 / ( 16 * 7 ) = 428571 ( 7 % error )
                sci_ptr->C4 = 16;   // BRFA = BaudRate = 48000000 / ( 16 * 6.5 ) = 461538.4
                break;
            case 921600UL:
                baud = 3;
                sci_ptr->C4 = 8;   // BRFA= 8 (8/32 = 0.25) BaudRate = 48000000 / ( 16 * 3.25 ) = 923076.9
                break;
               
            default:
              sci_ptr->C4 = 0;   // BRFA =0
              break;
         }
        
         sci_ptr->BDH = (uchar)((baud >> 8) & UART_BDH_SBR_MASK);
         sci_ptr->BDL = (uchar)(baud & UART_BDL_SBR_MASK);     
         break;

 

( it's not an optimal solution since the settings are valid only for 48 MHz Module Clock rate but it is enought for the TWRK60 BSP..).

Outcomes