正点原子IM6基于SDK2.2 > 串口1驱动



#include "fsl_iomuxc.h"
#include "fsl_uart.h"
#include "td_pcmaudio.h"
#include "td_touch.h"
#include "td_lcd_ui_manager.h"
#include "td_usart1_down_controller.h"
#include "td_emmc8g.h"
//格式化返回命令结果的方式
//static void TD_Usart1DownController_Send(unsigned char * pbuf, int len);
static unsigned char buf[4096];
/**********************************************************************************
正点原子imx6ull中的串口1链接到了板载的usb转串口CH340上
**********************************************************************************/
void TD_Usart1DownController_Init(void)
{
  IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX, 0U);
  IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX, 0U);
//  IOMUXC_SetPinConfig(IOMUXC_UART1_RX_DATA_UART1_RX, 
//                      IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |//设置快速翻转io
//                      //IOMUXC_SW_PAD_CTL_PAD_ODE_MASK |//设置开漏输出
//                      //IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |//设置为keeper,1=pull,0=keeper
//                      //IOMUXC_SW_PAD_CTL_PAD_HYS_MASK |//设置开启施密特触发器,可以过滤波形
//                      IOMUXC_SW_PAD_CTL_PAD_DSE(7U) |//输出驱动能力设置为R0/6,0=关闭,1=R0_260_Ohm___3_3V__150_Ohm_1_8V__240_Ohm_for_DDR
//                      IOMUXC_SW_PAD_CTL_PAD_SPEED(2U));// |//速度设置为100mhz,0=50mhz,3=200mhz
//                      //IOMUXC_SW_PAD_CTL_PAD_PKE_MASK |//pull或者keeper功能使能,两个功能互斥
//                      //IOMUXC_SW_PAD_CTL_PAD_PUS(2U));//上下拉设置,2=100k上拉,0=100k下拉
//  IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX, 
//                      IOMUXC_SW_PAD_CTL_PAD_SRE_MASK |//设置快速翻转io
//                      //IOMUXC_SW_PAD_CTL_PAD_ODE_MASK |//设置开漏输出
//                      //IOMUXC_SW_PAD_CTL_PAD_PUE_MASK |//设置为keeper,1=pull,0=keeper
//                      //IOMUXC_SW_PAD_CTL_PAD_HYS_MASK |//设置开启施密特触发器,可以过滤波形
//                      IOMUXC_SW_PAD_CTL_PAD_DSE(7U) |//输出驱动能力设置为R0/6,0=关闭,1=R0_260_Ohm___3_3V__150_Ohm_1_8V__240_Ohm_for_DDR
//                      IOMUXC_SW_PAD_CTL_PAD_SPEED(2U));// |//速度设置为100mhz,0=50mhz,3=200mhz
//                      //IOMUXC_SW_PAD_CTL_PAD_PKE_MASK |//pull或者keeper功能使能,两个功能互斥
//                      //IOMUXC_SW_PAD_CTL_PAD_PUS(2U));//上下拉设置,2=100k上拉,0=100k下拉
  
  uart_config_t uartConfig;
  uartConfig.baudRate_Bps = 2000000U;//2000000U;//115200U;
  uartConfig.parityMode = kUART_ParityDisabled;
  uartConfig.dataBitsCount = kUART_EightDataBits;
  uartConfig.stopBitCount = kUART_OneStopBit;
  uartConfig.txFifoWatermark = 2;
  uartConfig.rxFifoWatermark = 1;
  uartConfig.enableAutoBaudRate = false;
  uartConfig.enableTx = true;
  uartConfig.enableRx = true;
  UART_Init(UART1, &uartConfig, 80000000U);//当前串口的总时钟频率
  
  //UART_EnableInterrupts(UART1, kUART_RxDataReadyEnable);//kUART_TxEmptyEnable | kUART_RxDataReadyEnable);
  UART_EnableTx(UART1, 1);
  UART_EnableRx(UART1, 1);
}
/**********************************************************************************
串口命令处理
**********************************************************************************/
void TD_Usart1DownController_Server(void)
{
  int method, offect;
  //未接收到数据时返回
  if(!(UART1->USR2 & UART_USR2_RDR_MASK)) return;
  UART_ReadBlocking(UART1,buf,1);
  if (buf[0] != '#') return;
  UART_ReadBlocking(UART1,buf,1);
  int len = buf[0];
  UART_ReadBlocking(UART1,buf,len);
  switch(buf[0])
  {
    case 0x01://将384000个数据全部刷新到显存中
      method = buf[1];
      offect = (buf[2] << 16 | buf[3] << 8 | buf[4]);
      len = (buf[5] << 16 | buf[6] << 8 | buf[7]);
      for(int i = 0;i < len;i+=256){
        int tl = len - i > 256 ? 256 : len - i;
        UART_ReadBlocking(UART1,buf,tl);
        if(method == 0) TD_LcdUIManager_DrawBitmap((uint32_t *)buf,offect,tl / 4);
        else TD_LcdUIManager_DrawBitmapWithAlpha((uint32_t *)buf,offect,tl / 4);//带透明度
        offect += tl / 4;
      }
      TD_Usart1DownController_Send(buf, 0);
      break;
    case 0x02://指定的位置显示字符串
      buf[len] = 0;//设置结尾符号
      TD_LcdUIManager_Print((char*)buf+5,(buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4]);
      TD_Usart1DownController_Send(buf, 0);
      break;
    case 0x03://开启或者关闭背光
      TD_LcdUIManager_BackLedSetTo(buf[1]);
      TD_Usart1DownController_Send(buf, 0);
      break;
    case 0x04://清屏,或者染色某个区域,不支持透明度
      method = buf[1];
      if(method == 0) TD_LcdUIManager_FullRect(buf[2] << 8 | buf[3],buf[4] << 8 | buf[5],buf[6] << 8 | buf[7],buf[8] << 8 | buf[9],(buf[10] << 24) | (buf[11] << 16) | (buf[12] << 8) | buf[13]);
      else TD_LcdUIManager_DrawRect(buf[2] << 8 | buf[3],buf[4] << 8 | buf[5],buf[6] << 8 | buf[7],buf[8] << 8 | buf[9],(buf[10] << 24) | (buf[11] << 16) | (buf[12] << 8) | buf[13]);
      TD_Usart1DownController_Send(buf, 0);
      break;
    case 0x05://设置触屏的相关参数
      TD_Touch_SetOutToScreen(buf[1]);
      TD_Usart1DownController_Send(buf, 0);
      break;
    case 0x06://设置true会在发生触摸时同步发送到pc
      TD_Touch_SetOutToPC(buf[1]);
      TD_Usart1DownController_Send(buf, 0);
      break;
    case 0x07://获取当前的触点信息
      TD_Touch_ConfigColor((buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4]);
      TD_Usart1DownController_Send(buf, 0);
      break;
    case 0x08://设置左右声道的采样率和有效数据位数
      //TD_PcmAudio_SetSampleRote((buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4], buf[5], buf[6]);
      TD_Usart1DownController_Send(buf, 0);
      break;
    case 0x09://左声道开始播放pcm数据
      //buf[0] = TD_PcmAudio_PlayPcm(buf + 1, (len-1) / 2);
      TD_Usart1DownController_Send(buf, 1);
      break;
    case 0x0a://停止播放pcm,双声道同时停止
      //TD_PcmAudio_StopPlay();
      TD_Usart1DownController_Send(buf, 0);
      break;
    case 0x0b://emmc读取//每次最多4k
      len = buf[5];
      len = len > 0 && len <= 4 ? len : 0;
      offect = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
      if (len > 0) TD_Emmc8g_ReadBlocks(buf, offect, len);
      TD_Usart1DownController_Send(buf, len * 512);
      break;
    case 0x0c://emmc写入块,每次最多4k
      len = buf[5];
      len = len > 0 && len <= 4 ? len : 0;
      offect = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
      for(int i = 0;i < len * 512;i+=512){
        int tl = len - i > 512 ? 512 : len - i;
        UART_ReadBlocking(UART1,buf + i,tl);
        offect += tl / 4;
      }
      if (len > 0) TD_Emmc8g_WriteBlocks(buf, offect, len);
      TD_Usart1DownController_Send(buf, 0);
      break;
    case 0x0d://sd卡插入检测,获取sd卡是否插入
      //buf[0] = TD_SD_IsSdIn();
      TD_Usart1DownController_Send(buf, 1);
      break;
    case 0x0e://sd卡读取
      len = buf[5];
      len = len > 0 && len <= 4 ? len : 0;
      offect = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
      //if (len > 0) TD_SD_ReadBlocks(buf, offect, len);
      TD_Usart1DownController_Send(buf, len * 512);
      break;
    case 0x0f://sd写入块,每次最多4k
      len = buf[5];
      len = len > 0 && len <= 4 ? len : 0;
      offect = (buf[1] << 24) | (buf[2] << 16) | (buf[3] << 8) | buf[4];
      for(int i = 0;i < len * 512;i+=512){
        int tl = len - i > 512 ? 512 : len - i;
        UART_ReadBlocking(UART1,buf + i,tl);
        offect += tl / 4;
      }
      //if (len > 0) TD_SD_WriteBlocks(buf, offect, len);
      TD_Usart1DownController_Send(buf, 0);
      break;
    default:
      TD_Usart1DownController_Send("undefine", 8);
      break;
  }
}
/**********************************************************************************
格式化返回的数据
**********************************************************************************/
void TD_Usart1DownController_Send(const unsigned char * pbuf, int len)
{
  unsigned char tbuf[20];
  tbuf[0] = len >> 8;
  tbuf[1] = len;
  UART_WriteBlocking(UART1, tbuf, 2);
  if(len > 0) UART_WriteBlocking(UART1, pbuf, len);
}
/**********************************************************************************
单独线程方式运行
**********************************************************************************/
void TD_Usart1DownController_Run(void)
{
  TD_Usart1DownController_Init();
  while(1) TD_Usart1DownController_Server();
}