-
Notifications
You must be signed in to change notification settings - Fork 71
/
app_uart.c
executable file
·187 lines (138 loc) · 5.49 KB
/
app_uart.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
/********************************************************************************************************
* @file app_uart.c
*
* @brief for TLSR chips
*
* @author public@telink-semi.com;
* @date May. 12, 2018
*
* @par Copyright (c) Telink Semiconductor (Shanghai) Co., Ltd.
* All rights reserved.
*
* The information contained herein is confidential and proprietary property of Telink
* Semiconductor (Shanghai) Co., Ltd. and is available under the terms
* of Commercial License Agreement between Telink Semiconductor (Shanghai)
* Co., Ltd. and the licensee in separate contract or the terms described here-in.
* This heading MUST NOT be removed from this file.
*
* Licensees are granted free, non-transferable use of the information in this
* file under Mutual Non-Disclosure Agreement. NO WARRENTY of ANY KIND is provided.
*
*******************************************************************************************************/
#include "tl_common.h"
#include "drivers.h"
#define UART_DMA 1 //uart use dma
#define UART_NDMA 2 //uart not use dma
#define UART_MODE UART_DMA
#define LED1 GPIO_PD0
#define LED2 GPIO_PD1
#define LED3 GPIO_PD2
volatile unsigned char uart_rx_flag=0;
volatile unsigned char uart_dmairq_tx_cnt=0;
volatile unsigned char uart_dmairq_rx_cnt=0;
volatile unsigned int uart_ndmairq_cnt=0;
volatile unsigned char uart_ndmairq_index=0;
#if (UART_MODE==UART_DMA)
#define UART_DATA_LEN 12 //data max ? (UART_DATA_LEN+4) must 16 byte aligned
typedef struct{
unsigned int dma_len; // dma len must be 4 byte
unsigned char data[UART_DATA_LEN];
}uart_data_t;
uart_data_t rec_buff = {0, {0, } };
uart_data_t trans_buff = {12, {'H','e','l','l','o','W','o','r','l','d','\r','\n'} };
#elif(UART_MODE==UART_NDMA)
#define rec_buff_Len 16
#define trans_buff_Len 16
__attribute__((aligned(4))) unsigned char rec_buff[rec_buff_Len]={0};
__attribute__((aligned(4))) unsigned char trans_buff[trans_buff_Len] = {'H','e','l','l','o',' ','W','o','r','l','d',' ',' ',' ','\r','\n'};
#endif
void app_uart_init(void)
{
//WaitMs(100); //leave enough time for SWS_reset when power on
//note: dma addr must be set first before any other uart initialization! (confirmed by sihui)
uart_recbuff_init( (unsigned char *)&rec_buff, sizeof(rec_buff));
// uart tx/rx pin set
// TB01 : UART_TX_PB1 UART_RX_PB0
// TB02 : UART_RX_PB0 UART_RX_PA0
uart_gpio_set(UART_TX_PB1, UART_RX_PB0);
uart_reset(); //will reset uart digital registers from 0x90 ~ 0x9f, so uart setting must set after this reset
//baud rate: 9600
#if (CLOCK_SYS_CLOCK_HZ == 16000000)
// uart_init(118, 13, PARITY_NONE, STOP_BIT_ONE);
uart_init(9, 13, PARITY_NONE, STOP_BIT_ONE);
#elif (CLOCK_SYS_CLOCK_HZ == 24000000)
uart_init(249, 9, PARITY_NONE, STOP_BIT_ONE);
#endif
#if (UART_MODE==UART_DMA)
uart_dma_enable(1, 1); //uart data in hardware buffer moved by dma, so we need enable them first
irq_set_mask(FLD_IRQ_DMA_EN);
dma_chn_irq_enable(FLD_DMA_CHN_UART_RX | FLD_DMA_CHN_UART_TX, 1); //uart Rx/Tx dma irq enable
uart_irq_enable(0, 0); //uart Rx/Tx irq no need, disable them
#elif(UART_MODE==UART_NDMA)
uart_dma_enable(0, 0);
irq_clr_mask(FLD_IRQ_DMA_EN);
dma_chn_irq_enable(FLD_DMA_CHN_UART_RX | FLD_DMA_CHN_UART_TX, 0);
uart_irq_enable(1,0); //uart RX irq enable
uart_ndma_irq_triglevel(1,0); //set the trig level. 1 indicate one byte will occur interrupt
#endif
irq_enable();
}
void app_uart_loop(void)
{
WaitMs(1000);
#if (UART_MODE==UART_DMA)
uart_dma_send((unsigned char*)&rec_buff);
WaitMs(300);
uart_dma_send((unsigned char*)&trans_buff);
#elif(UART_MODE==UART_NDMA)
for(unsigned char i=0;i<trans_buff_Len;i++){
uart_ndma_send_byte(trans_buff[i]);
}
if(uart_rx_flag>0){
uart_ndmairq_cnt=0; //Clear uart_ndmairq_cnt
uart_rx_flag=0;
for(unsigned char i=0;i<trans_buff_Len;i++){
uart_ndma_send_byte(rec_buff[i]);
}
}
#endif
}
#define rec_buff_Len 16
#define trans_buff_Len 16
volatile unsigned int cnt=0;
void app_uart_irq_proc(void)
{
#if (UART_MODE==UART_DMA)
unsigned char uart_dma_irqsrc;
//1. UART irq
uart_dma_irqsrc = dma_chn_irq_status_get();///in function,interrupt flag have already been cleared,so need not to clear DMA interrupt flag here
if(uart_dma_irqsrc & FLD_DMA_CHN_UART_RX){
dma_chn_irq_status_clr(FLD_DMA_CHN_UART_RX);
uart_dmairq_rx_cnt++;
//Received uart data in rec_buff, user can copy data here
}
if(uart_dma_irqsrc & FLD_DMA_CHN_UART_TX){
dma_chn_irq_status_clr(FLD_DMA_CHN_UART_TX);
uart_dmairq_tx_cnt++;
}
#elif(UART_MODE==UART_NDMA)
static unsigned char uart_ndma_irqsrc;
uart_ndma_irqsrc = uart_ndmairq_get(); ///get the status of uart irq.
if(uart_ndma_irqsrc){
//cycle the four registers 0x90 0x91 0x92 0x93,in addition reading will clear the irq.
if(uart_rx_flag==0){
rec_buff[uart_ndmairq_cnt++] = reg_uart_data_buf(uart_ndmairq_index);
uart_ndmairq_index++;
uart_ndmairq_index &= 0x03;// cycle the four registers 0x90 0x91 0x92 0x93, it must be done like this for the design of SOC.
if(uart_ndmairq_cnt%16==0&&uart_ndmairq_cnt!=0){
uart_rx_flag=1;
}
}
else{
read_reg8(0x90+ uart_ndmairq_index);
uart_ndmairq_index++;
uart_ndmairq_index &= 0x03;
}
}
#endif
}