gonzui


Format: Advanced Search

mtkernel_3/device/ser/sysdepend/stm32l4/ser_stm32l4.cbare sourcepermlink (0.01 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    Device Driver for micro T-Kernel for μT-Kernel 3.0
    4:  *
    5:  *    Copyright (C) 2020-2021 by Ken Sakamura.
    6:  *    This software is distributed under the T-License 2.2.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by TRON Forum(http://www.tron.org) at 2021/08.
   10:  *
   11:  *----------------------------------------------------------------------
   12:  */
   13: 
   14: #include <sys/machine.h>
   15: #ifdef CPU_STM32L4
   16: 
   17: #include <tk/tkernel.h>
   18: #include "../../ser.h"
   19: #include "../../../include/dev_def.h"
   20: #if DEV_SER_ENABLE
   21: /*
   22:  *      ser_stm32l4.c
   23:  *      Serial communication device driver
   24:  *      System dependent processing for STM32L4
   25:  */
   26: 
   27: /*----------------------------------------------------------------------
   28:  * Device register base address
   29:  */
   30: const LOCAL UW ba[DEV_SER_UNITNM] = { USART1_BASE, USART2_BASE, USART3_BASE};
   31: 
   32: #define USART_CR1(x)    (ba[x] + USARTx_CR1)       /* Control register 1 */
   33: #define USART_CR2(x)    (ba[x] + USARTx_CR2)       /* Control register 2 */
   34: #define USART_CR3(x)    (ba[x] + USARTx_CR3)       /* Control register 3 */
   35: #define USART_BRR(x)    (ba[x] + USARTx_BRR)       /* baud rate register */
   36: #define USART_GTPR(x)   (ba[x] + USARTx_GTPR)     /* Guard time and Priscaler register */
   37: #define USART_RTOR(x)   (ba[x] + USARTx_RTOR)     /* Receiver timeout register */
   38: #define USART_RQR(x)    (ba[x] + USARTx_RQR)       /* Request register */
   39: #define USART_ISR(x)    (ba[x] + USARTx_ISR)       /* Interrupts and status register */
   40: #define USART_ICR(x)    (ba[x] + USARTx_ICR)       /* Interrupt flag clear register */
   41: #define USART_RDR(x)    (ba[x] + USARTx_RDR)       /* Received data register */
   42: #define USART_TDR(x)    (ba[x] + USARTx_TDR)       /* Transmission data register */
   43: 
   44: /*----------------------------------------------------------------------
   45:  * Device low-level control data
   46: */
   47: typedef struct {
   48:         UW     mode;               // Serial mode
   49:         UW     speed;              // Spped (bit rate)
   50: } T_DEV_SER_LLDEVCB;
   51: 
   52: LOCAL T_DEV_SER_LLDEVCB         ll_devcb[DEV_SER_UNITNM];
   53: 
   54: /*----------------------------------------------------------------------
   55:  * Interrupt handler
   56:  */
   57: void usart_inthdr( UINT intno)
   58: {
   59:         UW     data, err;
   60:         UW     isr;
   61:         W      unit;
   62: 
   63:         unit = intno -INTNO_USART1;
   64:         
   65:         isr = in_w(USART_ISR(unit));                   // Get interrupt factor
   66: 
   67:         out_w(USART_ICR(unit), USART_ICR_ALL);         // Clear Interrupt
   68:         ClearInt(intno);
   69: 
   70:         /* Reception process */
   71:         if( isr & USART_ISR_RXNE) {
   72:                 data = in_w(USART_RDR(unit));
   73:                 dev_ser_notify_rcv(unit, data);       /* Notify the main process of data reception. */
   74:         }
   75: 
   76:         /* Transmission process */
   77:         if( isr & USART_ISR_TXE ) {
   78:                 if( dev_ser_get_snddat(unit, &data)) {
   79:                         out_w(USART_TDR(unit), data);
   80:                 } else {
   81:                         *(_UW*)( USART_CR1(unit)) &= ~USART_CR1_TXEIE;       // Disable TXE interrupt
   82:                 }
   83:         }
   84: 
   85:         /* Error handling */
   86:         err = isr & USART_ISR_ERR;
   87:         if(err) {
   88:                 dev_ser_notify_err(unit, err);        /* Notify the main process of this error. */
   89:         }
   90: }
   91: 
   92: /*----------------------------------------------------------------------
   93:  * Set mode & Start communication
   94:  */
   95: #define MASK_MODE_CR1   (USART_CR1_M1| USART_CR1_M0|USART_CR1_PS|USART_CR1_PCE)
   96: 
   97: LOCAL void start_com(UW unit, UW mode, UW speed)
   98: {
   99: 
  100: 
  101:         out_w(USART_CR2(unit), mode & USART_CR2_STOP);         // Set stop-bit
  102:         out_w(USART_CR3(unit), mode & (USART_CR3_RTSE | USART_CR3_CTSE)); // Set RTS/CTS
  103:         out_w(USART_BRR(unit), speed);                         // Set communication Speed
  104: 
  105:         /* Set mode & Start communication */
  106:         out_w(USART_CR1(unit),
  107:                 USART_CR1_RXNEIE | USART_CR1_PEIE             // Unmask Receive & Parity error interrupt
  108:                 | (mode & MASK_MODE_CR1 )                     // Set word length & parity
  109:                 | USART_CR1_UE | USART_CR1_RE | USART_CR1_TE  // USART enable
  110:         );
  111: }
  112: 
  113: /*----------------------------------------------------------------------
  114:  * Stop communication
  115:  */
  116: LOCAL void stop_com(UW unit)
  117: {
  118:         if(unit != DEVCNF_SER_DBGUN) {
  119:                 out_w(USART_CR1(unit), 0);
  120:         } else {       /* Used by T-Monitor */
  121:                 out_w(USART_CR1(unit), USART_CR1_DEBUG);
  122:         }
  123: }
  124: 
  125: /*----------------------------------------------------------------------
  126:  * Low level device control
  127:  */
  128: EXPORT ER dev_ser_llctl( UW unit, INT cmd, UW parm)
  129: {
  130:         ER     err = E_OK;
  131: 
  132:         switch(cmd) {
  133:         case LLD_SER_MODE:     /* Set Communication mode */
  134:                 ll_devcb[unit].mode = parm;
  135:                 break;
  136:         
  137:         case LLD_SER_SPEED:    /* Set Communication Speed */
  138:                 ll_devcb[unit].speed = (TMCLK*1000*1000)/parm;
  139:                 break;
  140:         
  141:         case LLD_SER_START:    /* Start communication */
  142:                 out_w(USART_CR1(unit), 0);
  143:                 out_w(USART_ICR(unit), USART_ICR_ALL);                        // Clear interrupt
  144:                 ClearInt(INTNO_USART1 + unit);
  145:                 EnableInt(INTNO_USART1 + unit, DEVCNF_SER_INTPRI);    // Enable Interrupt
  146:                 start_com( unit, ll_devcb[unit].mode, ll_devcb[unit].speed);
  147:                 break;
  148:         
  149:         case LLD_SER_STOP:
  150:                 DisableInt(INTNO_USART1 + unit);
  151:                 stop_com(unit);
  152:                 break;
  153: 
  154:         case LLD_SER_SEND:
  155:                 if(in_w(USART_ISR(unit)) & USART_ISR_TXE) {
  156:                         out_w(USART_TDR(unit), parm);                        // Set Transmission data
  157:                         *(_UW*)( USART_CR1(unit)) |= USART_CR1_TXEIE;        // Enable TXE interrupt
  158:                         err = E_OK;
  159:                 } else {
  160:                         err = E_BUSY;
  161:                 }
  162:                 break;
  163: 
  164:         case LLD_SER_BREAK:    /* Send Break */
  165:                 if(parm) {
  166:                         out_w(USART_RQR(unit), USART_RQR_SBKRQ);
  167:                 }
  168:                 break;
  169:         }
  170: 
  171:         return err;
  172: }
  173: 
  174: /*----------------------------------------------------------------------
  175:  * Device initialization
  176:  */
  177: EXPORT ER dev_ser_llinit( T_SER_DCB *p_dcb)
  178: {
  179:         const T_DINT   dint = {
  180:                 .intatr       = TA_HLNG,
  181:                 .inthdr       = usart_inthdr,
  182:         };
  183:         UW     unit;
  184:         ER     err;
  185: 
  186:         unit = p_dcb->unit;
  187: 
  188: #if DEVCONF_SER_INIT_MCLK
  189:         switch(unit) {
  190:         case 0:        // USART1
  191:                 *(_UW*)RCC_APB2ENR |= RCC_APB2ENR_USART1EN;
  192:                 break;
  193:         case 1:        // USART2
  194:                 *(_UW*)RCC_APB1ENR1 |= RCC_APB1ENR1_USART2EN;
  195:                 break;
  196:         case 2:        // USART3
  197:                 *(_UW*)RCC_APB1ENR1 |= RCC_APB1ENR1_USART3EN;
  198:                 break;
  199:         }
  200: #endif
  201: 
  202:         /* USART device initialize (Disable USART & Disable all interrupt) */
  203:         stop_com(unit);
  204: 
  205:         /* Device Control block Initizlize */
  206:         p_dcb->intno_rcv = p_dcb->intno_snd = INTNO_USART1 + unit;
  207: 
  208:         /* Interrupt handler definition */
  209:         err = tk_def_int((INTNO_USART1 + unit), &dint);
  210: 
  211:         return err;
  212: }
  213: 
  214: #endif          /* DEV_SER_ENABLE */
  215: #endif          /* CPU_STM32L4 */