29.04.2015 Views

UART - Microchip Taiwan

UART - Microchip Taiwan

UART - Microchip Taiwan

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Microchip</strong> 16-bit MCU<br />

內 建 周 邊 模 組<br />

<strong>UART</strong> Module<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 1


Session Agenda<br />

• Module Overview<br />

• <strong>UART</strong> Transmission<br />

• <strong>UART</strong> Reception<br />

• Additional Features<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 2


<strong>UART</strong> - Overview<br />

• Serial transmission and reception<br />

8-bit (Odd,Even or No Parity) or 9-bit data<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Full-duplex, asynchronous communication<br />

Support for communication protocols such as RS-<br />

232, RS-422, RS-485 and LIN<br />

4-deep Transmit and Receive buffers<br />

Transmit and Receive interrupts<br />

Error detection<br />

ec Support for receiver addressing<br />

Loopback mode<br />

Alternate TX/RX pins on some devices<br />

Wake-up from SLEEP<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 3


ABAUD<br />

<strong>UART</strong> - Block Diagram<br />

ICx<br />

0<br />

1<br />

To Input Capture<br />

Baud Rate<br />

Generator<br />

÷16<br />

Divider<br />

UxRX<br />

0<br />

UxRSR<br />

1<br />

LPBACK<br />

Module Control /<br />

Error Handling<br />

Logic<br />

Load UxRSR<br />

to Buffer<br />

UxRXREG<br />

P F<br />

Error Status<br />

UxTX<br />

Parity<br />

Gen.<br />

UxTSR<br />

Load UxTSR<br />

UTXBRK<br />

UxTXREG<br />

LIN Bus<br />

Support<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 4


<strong>UART</strong> - Baud Rate<br />

Generator<br />

• Dedicated 16-bit Baud Rate Generator<br />

• Baud Rate controlled by UxBRG register (x =<br />

1or2)<br />

<br />

Baud Rate = Fcy / ( 16 * (UxBRG + 1) ) where<br />

Fcy = Instruction ti Cycle Frequency<br />

• Both transmitting and receiving devices must<br />

use same Baud Rate<br />

• Bits are transmitted and/or received at the<br />

rate defined by the Baud Rate<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 5


<strong>UART</strong> - Transmission<br />

• <strong>UART</strong> module 的 致 能 是 使 用 UxMODE 暫 存 器 中<br />

的 <strong>UART</strong>EN bit<br />

• 只 有 在 下 列 條 件 成 立 後 傳 送 才 開 始 :<br />

<br />

欲 被 傳 送 的 資 料 被 寫 入 Transmit Buffer 而 且 UxSTA 中<br />

的 UTXEN 被 設 定 為 1<br />

Start Bit<br />

TxD<br />

Bit 0 Bit 1 Bit 2 Bit 3 Bit 4 Bit 5 Bit 6 Bit 7 Stop Bit<br />

TRMT<br />

TxIF<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 6


<strong>UART</strong><br />

– Transmission<br />

(contd.)<br />

• <strong>UART</strong> module is enabled by setting the <strong>UART</strong>EN bit<br />

in the UxMODE register<br />

R/W-0 U-0 R/W-0 U-0 U-0 R/W-0 U-0 U-0<br />

<strong>UART</strong>EN - USIDL - - ALTIO -<br />

-<br />

bit15 14 13 12 11 10 9 bit8<br />

R/W-0 R/W-0 R/W-0 U-0 U-0 R/W-0 R/W-0 R/W-0<br />

WAKE LPBACK ADAUD - - PDSEL PDSEL STSEL<br />

Bit 7 6 5 4 3 2 1 bit 0<br />

• Transmission starts only when:<br />

<br />

<br />

The data to be transmitted is written to the buffer, AND<br />

The UTXEN bit in the UxSTA register is set<br />

R/W-0 U-0 U-0 U-0 R/W-0 R/W-0 R-0 R-1<br />

UTXISEL - -<br />

- UTXBRK<br />

UTXEN<br />

UTXBF<br />

TRMT<br />

bit15 14 13 12 11 10 9 bit8<br />

R/W-0 R/W-0 R/W-0 R-1 R-0 R-0 R/C-0 R-0<br />

URXISEL1 URXISEL0<br />

ADDEN<br />

RIDLE PERR<br />

FERR<br />

OERR<br />

URXDA<br />

Bit 7 6 5 4 3 2 1 bit 0<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 7


<strong>UART</strong> - Transmission<br />

(contd.)<br />

• 開 始 傳 送 後 最 先 被 送 出 的 為 START bit<br />

<br />

Low level on UxTX pin for 1 bit time<br />

• 接 著 就 是 資 料 字 元 組 本 身<br />

<br />

<br />

<br />

LSB first , MSB later and parity bit last<br />

Data format (8 or 9 bits) and parity type (even, odd<br />

or no parity) configured by PDSEL bits in the<br />

UxMODE register<br />

No parity for 9-bit data<br />

R/W-0 R/W-0 R/W-0 U-0 U-0 R/W-0 R/W-0 R/W-0<br />

WAKE LPBACK ABAUD - - PDSEL1 PDSEL0 STSEL<br />

bit7 6 5 4 3 2 1 bit0<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 8


<strong>UART</strong> - Transmission<br />

(contd.)<br />

• The last bit transmitted is a STOP bit<br />

<br />

<br />

High level on UxTX pin for 1 or 2 bit times<br />

Number of STOP bits configured by STSEL bit<br />

in the UxMODE register<br />

R/W-0 R/W-0 R/W-0 U-0 U-0 R/W-0 R/W-0 R/W-0<br />

WAKE LPBACK ABAUD - - PDSEL1 PDSEL0 STSEL<br />

bit7 6 5 4 3 2 1 bit0<br />

• 在 USTA UxSTA 暫 存 器 的 TRMT status t bit 作 用<br />

<br />

Bit is cleared if Transmit Shift Register (UxTSR)<br />

is busy or a transmission is pending<br />

R/W-0 U-0 U-0 U-0 R/W-0 R/W-0 R-0 R-1<br />

UTXISEL - -<br />

- UTXBRK<br />

UTXEN<br />

UTXBF<br />

TRMT<br />

bit15 14 13 12 11 10 9 bit8<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 9


<strong>UART</strong> - Transmit Buffers<br />

• 4-deep Transmit FIFO Buffer<br />

<br />

<br />

<br />

<br />

只 有 buffer 中 的 第 一 個 字 元 組 為 memory-<br />

mapped , 所 以 只 要 對 UxTXREG 寫 入 即 可<br />

在 buffer 中 的 Characters 會 以 先 進 先 出 的 順 序 被<br />

寫 入 UxTSR 後 被 傳 送 出 去<br />

所 有 的 資 料 (8 or 9d ata bits) 會 一 次 寫 入 UxTSR<br />

The UTXBF status bit in the UxSTA register<br />

indicates whether the buffer is full<br />

R/W-0 U-0 U-0 U-0 R/W-0 R/W-0 R-0 R-1<br />

UTXISEL - -<br />

- UTXBRK UTXEN UTXBF TRMT<br />

bit15 14 13 12 11 10 9 bit8<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 10


<strong>UART</strong> - Transmit Interrupts<br />

• UxTXIF bit 用 來 指 出 有 Transmit Interrupt 發 生 , 硬 體 中 斷<br />

的 致 能 則 由 UxTXIE bit 來 控 制<br />

當 UxSTA 暫 存 器 中 的 UTXISEL bit = 1<br />

‣ 中 斷 發 生 於 Transmit Buffer 完 全 清 空 時<br />

‣ 用 於 傳 送 4 個 字 元 組 區 塊 的 資 料<br />

當 UxSTA 暫 存 器 中 的 UTXISEL bit = 0<br />

‣ 每 當 有 字 元 組 被 送 至 UxTSR 時 就 產 生 中 斷 條 件<br />

‣ 用 於 傳 送 單 個 字 元 組 區 塊 的 資 料<br />

‣ 在 此 模 式 , 一 旦 設 定 UTXEN bit = 1 後 就 馬 上 會 產 生 中 斷<br />

R/W-0 U-0 U-0 U-0 R/W-0 R/W-0 R-0 R-1<br />

UTXISEL - -<br />

- UTXBRK<br />

UTXEN<br />

UTXBF<br />

TRMT<br />

bit15 14 13 12 11 10 9 bit8<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 11


TxD Interrupt Timing<br />

Transmission 8-bit or 9-bit Data<br />

Transmission Back to Back<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 12


<strong>UART</strong> Baud Rate Generator<br />

• 有 專 用 的 16-bit baud rate generator ( 不 佔 Timer )<br />

<br />

Baud Rate = Fcy / (16*UxBRG+1)<br />

or<br />

UxBRG = [Fcy / ( 16* Baud Rate) ] - 1<br />

• Baud Rate 計 算 的 範 例<br />

– 假 設<br />

Fosc = 16 Mhz<br />

<br />

<br />

Fosc = 16MHz , Fcy=4MHz<br />

Descried Baud Rate : 19200 bps<br />

UxBRG = [ 4000000/(16*19200)] -1<br />

=13-1 =12<br />

Baud Rate Error = 4000000/(16(12+1))=19230 bps<br />

Error % = (19230-19200) 19200) / 19200 = 0.16%<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 13


<strong>UART</strong> - Reception<br />

• <strong>UART</strong> Receiver 在 偵 測 到 START bit 後<br />

即 進 入 Active 狀 態<br />

, 開 始 接 收 資 料<br />

• 資 料 由 LSB 開 始 被 移 入 Receive shift<br />

Register (UxRSR) , 若 有 parity bit 的<br />

話 會 尾 隨 資 之 後<br />

Data format 與 parity type (<br />

使 用 在<br />

UxMODE 中 的 PDSEL bits 來 設 定 ) 必 需<br />

規 劃 成 與 傳 送 端 的 設 定 相 同<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 14


<strong>UART</strong> - Reception (contd.)<br />

• UxRSR 在 收 到 STOP bit 後 停 止 shift<br />

data ( STOP 位 元 為 1or2bit)<br />

STOP bits 的 數 量 必 須 設 定 與 傳 送 端 的 一 樣<br />

(STSEL bit in the UxMODE register)<br />

UxSTA 暫 存 器 中 的 RIDLE 位 元 可 用 來 指 明<br />

接 收 移 位 暫 存 器 是 否 處 於 閒 置 ( Idle ) 狀 態<br />

‣ 1 : Idle<br />

‣ 0:Active<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 15


<strong>UART</strong> - Receive Buffers<br />

• 4-deep Receive FIFO Buffer<br />

All 8 (or 9) data bits, as well as Error flags,<br />

are buffered<br />

FIFO buffer 中 的 第 一 個 字 元 組 為 memorymapped<br />

( 只 需 使 用 UxRXREG 來 讀 取 )<br />

The in the 位 於 UxSTA register 的 error<br />

flags 用 於 反 應 在 FIFO 的 第 一 個 字 元 組 的<br />

error states<br />

位 於 UxSTA 暫 存 器 的 URXDA status bit 用<br />

來 指 明 是 否 任 何 的 資 料 仍 存 在 FIFO buffer<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 16


<strong>UART</strong> - Receive Interrupts<br />

• <strong>UART</strong> module 以 設 定 UxRXIF bit 來 指 出 有 Receive<br />

Interrupt 發 生 , 若 UxRXIE bit 也 被 設 定 為 1 則 會 發 生<br />

硬 體 中 斷<br />

• 接 收 中 斷 與 Receive Buffer 之 關 係 如 下 :<br />

When URXISEL bits in the UxSTA register = 11<br />

‣ Interrupt occurs when buffer becomes full<br />

‣ Used for receiving a block of 4 characters<br />

When URXISEL bits = 10<br />

‣ Interrupt when buffer has 3 characters<br />

‣ Used for receiving a block of 3 characters<br />

When URXISEL bits = 01 or 00<br />

‣ Interrupt whenever a character is received<br />

‣ Used for receiving a single character<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 17


<strong>UART</strong> – 可 偵 測 的 Errors<br />

• Parity Error<br />

<br />

<br />

When received parity does not match the parity calculated<br />

by module from received data<br />

Indicated by PERR bit in the UxSTA register set<br />

• Framing Error<br />

<br />

<br />

When a STOP bit is expected on UxRX pin but a low logic<br />

level is detected<br />

Indicated by FERR bit in the UxSTA register set<br />

• Receive Overrun Error<br />

<br />

<br />

When the Receive Buffer is full and a 5 th character is<br />

received<br />

Indicated by OERR bit in the UxSTA register set<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 18


<strong>UART</strong> - Address Detection<br />

• 工 作 條 件 : 當 <strong>UART</strong> 操 作 於 9-bit mode (PDSEL =<br />

11), 而 且 在 UsSTA 暫 存 器 的 控 制 位 元 ADDEN<br />

被 設 定 為 1<br />

• <strong>UART</strong> module 將 會 等 待 並 只 接 受 Address word (<br />

一 組 9-bit 的 資 料 而 且 第 9 位 元 為 1)<br />

‣ 在 此 階 段 , 在 UxSTA 暫 存 器 的 URXISELx 位 元<br />

要 被 設 定 為 00 or 01 – 一 有 資 料 就 中 斷<br />

• 當 接 收 到 位 址 資 料 , 必 須 使 用 程 式 來 檢 查 收 到 的<br />

位 址 與 自 身 之 位 址 是 否 相 符<br />

• 如 果 位 址 相 符<br />

, 則 清 除 ADDEN 位 元 以 便 接 收 位<br />

址 資 料 後 的 一 般 資 料 (9-bit 的 資 料 但 第 9 位 元 為<br />

0 )<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 19


<strong>UART</strong> – 對 LIN Support<br />

• 可 以 直 接 傳 送 Break Characters (13 bit 的 Low)<br />

<br />

A Break character can be transmitted by setting the<br />

UTXBRK bit in the UxSTA register for at least 13 bit times<br />

R/W-0 U-0 U-0 U-0 R/W-0 R/W-0 R-0 R-1<br />

UTXISEL - -<br />

- UTXBRK UTXEN UTXBF TRMT<br />

bit15 14 13 12 11 10 9 bit8<br />

• Autobaud Detection – 使 用 UxMODE.ABAUD 控 制<br />

<br />

<br />

The UxRX pin is internally routed to an Input Capture pin<br />

(IC1 for <strong>UART</strong>1, IC2 for <strong>UART</strong>2)<br />

Used for capturing both edges of START bit for determining<br />

baud rate<br />

R/W-0 R/W-0 R/W-0 U-0 U-0 R/W-0 R/W-0 R/W-0<br />

WAKE LPBACK<br />

ABAUD - -<br />

PDSEL1<br />

PDSEL0<br />

STSEL<br />

bit7 6 5 4 3 2 1 bit0<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 20


<strong>UART</strong> - 其 他 有 用 的 附 加 功 能<br />

• Alternate I/O<br />

<br />

<br />

有 些 dsPIC30F 系 列 的 <strong>UART</strong> 有 alternate TX/RX pins<br />

主 要 用 於 當 原 有 接 腳 與 其 它 功 能 有 衝 突 時 使 用<br />

• Loopback Mode – 測 試 模 式<br />

<br />

UxTX pin internally connected to UxRX pin<br />

• Wake-up from SLEEP<br />

<br />

Device 在 偵 測 到 START bit 時 能 wake up 處 於<br />

SLEEP 狀 態 的 CPU<br />

R/W-0 U-0 R/W-0 U-0 U-0 R/W-0 U-0 U-0<br />

<strong>UART</strong>EN - USIDL - - ALTIO -<br />

-<br />

bit15 14 13 12 11 10 9 bit8<br />

R/W-0 R/W-0 R/W-0 U-0 U-0 R/W-0 R/W-0 R/W-0<br />

WAKE LPBACK<br />

ABAUD - -<br />

PDSEL1<br />

PDSEL0<br />

STSEL<br />

bit7 6 5 4 3 2 1 bit0<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 21


Initialize the <strong>UART</strong> – 使 用 <strong>UART</strong><br />

相 關 的 Library<br />

Close<strong>UART</strong>1( (); /* Configure uart1 receive and transmit interrupt */<br />

ConfigInt<strong>UART</strong>1 (<strong>UART</strong>_RX_INT_EN & <strong>UART</strong>_RX_INT_PR6 &<br />

<strong>UART</strong>_TX_INT_DIS & <strong>UART</strong>_TX_INT_PR2);<br />

/* Setup the Buad Rate Generator */<br />

baudvalue = 95; //UxBRG = ( (FCY/Desired Baud Rate)/16) – 1<br />

//UxBRG = ( (4000000/9600)/16-1) = 25<br />

/* Configure <strong>UART</strong>1 module to transmit 8 bit data with one stopbit. Also Enable loopback mode */<br />

U1MODEvalue = <strong>UART</strong>_EN & <strong>UART</strong>_IDLE_CON &<br />

<strong>UART</strong>_DIS_WAKE & <strong>UART</strong>_DIS_LOOPBACK &<br />

<strong>UART</strong>_DIS_ABAUD & <strong>UART</strong>_NO_PAR_8BIT &<br />

<strong>UART</strong>_1STOPBIT & <strong>UART</strong>_ALTRX_ALTTX;<br />

U1STAvalue = <strong>UART</strong>_INT_TX_BUF_EMPTY &<br />

<strong>UART</strong>_TX_PIN_NORMAL &<br />

<strong>UART</strong>_TX_ENABLE & <strong>UART</strong>_INT_RX_CHAR &<br />

<strong>UART</strong>_ADR_DETECT_DIS &<br />

<strong>UART</strong>_RX_OVERRUN_CLEAR;<br />

Open<strong>UART</strong>1(U1MODEvalue, U1STAvalue, baudvalue);<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 22


Initialize the <strong>UART</strong> – 直 接 寫 入 各<br />

控 制 暫 存 器<br />

void<br />

{<br />

<strong>UART</strong>1_Initial(void)<br />

U1MODE = 0x8800 ;<br />

U1STA = 0x2400 ;<br />

U1BRG = 25 ; // Baud-Rate = 9600 when Fcy = 4M , BRGH = 0<br />

Ctrl_U1RX = INPUT ;<br />

Ctrl_U1TX = OUTPUT ;<br />

}<br />

• 優 點 : 簡 潔 , 不 需 參 考 預 先 定 義 好 的 參 數 項<br />

• 缺 點 : 不 容 易 維 護 與 移 轉<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 23


Write data To <strong>UART</strong>1<br />

• 使 用 Library 中 的 現 成 函 數 (uart.h)<br />

putc<strong>UART</strong>1() , putc<strong>UART</strong>2()<br />

puts<strong>UART</strong>1() , puts<strong>UART</strong>2()<br />

Write<strong>UART</strong>1() , Write<strong>UART</strong>2()<br />

• 使 用 printf() 函 數 (stdio.h)<br />

Standard ANSI C syntax<br />

Support the Float format<br />

Extra code size<br />

Heap Needed<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 24


Read data from <strong>UART</strong>1<br />

• 使 用 Library 中 的 現 成 函 數 (uart.h)<br />

getc<strong>UART</strong>1() , getc<strong>UART</strong>2()<br />

gets<strong>UART</strong>1() , gets<strong>UART</strong>2()<br />

Read<strong>UART</strong>1() , Read<strong>UART</strong>2()<br />

DataRdy<strong>UART</strong>1()<br />

DataRdy<strong>UART</strong>2()<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 25


Read data from <strong>UART</strong>1<br />

• Suggest to use the Interrupt Method<br />

<br />

<br />

<br />

Why? It is real time and can run with background<br />

Set U1RXIE bit in IEC0 register<br />

Set the U1RXIP to a higher interrupt priority<br />

• U1RXIF – <strong>UART</strong>1 Receiver Interrupt Flag<br />

<br />

<br />

<br />

It should be cleared in software routine<br />

This doesn’t like the PIC18, nee to read the REREG to<br />

clear the RCIF flag<br />

Refer to the URXISEL control setting for receiver<br />

FIFO depth selection in the U1STA Register<br />

• URXDA – Receiver Buffer Data Available bit<br />

<br />

1 : Receiver Data has unread buffer<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 26


Read data from <strong>UART</strong>1<br />

• Using Read<strong>UART</strong>1( )<br />

unsigned int Read<strong>UART</strong>1(void)<br />

{<br />

if(U1MODEbits.PDSEL == 3)<br />

return (U1RXREG);<br />

else<br />

return (U1RXREG & 0xFF);<br />

}<br />

• Read receiver data from Interrupt<br />

void _ISR _U1RXInterrupt(void)<br />

{<br />

Rec_Buffer = Read<strong>UART</strong>1( ); // Read data from Receiver<br />

FIFO<br />

Rec_Flag = 1;<br />

// Set the Received Flag<br />

IFS0bits.U1RXIF = 0 ;<br />

// Clear Interrupt Flag<br />

}<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 27


<strong>UART</strong> 練 習<br />

• 使 用 printf() 來 將 字 串 輸 出<br />

• 使 用 printf() 將 浮 點 數 輸 出<br />

• 使 用 MPLAB SIM 的 output window 來 觀 查 輸 出<br />

<br />

必 需 設 定 Debugger -> Settings 中 的 <strong>UART</strong> IO 項 目<br />

• 系 統 變 數 __C30_<strong>UART</strong> 可 以 被 更 改 來 指 定 printf() 的 輸<br />

出 為 <strong>UART</strong>1 or <strong>UART</strong>2 !!<br />

• 使 用 printf() 時 必 需 注 意 LINK30 的 HEAP 要 設 定<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 28


Build Options 的 設 定<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 29


Simulator Settings 的 設 定<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 30


SIM Uart1 的 輸 出 結 果<br />

dsPIC Peripheral Module Training – RTC <strong>Taiwan</strong><br />

SLIDE 31

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!