source: azure_iot_hub_f767zi/trunk/asp_baseplatform/arch/arm_m_gcc/stm32f7xx/chip_serial.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 24.8 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2008-2011 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 * Copyright (C) 2015 by 3rd Designing Center
9 * Imageing System Development Division RICOH COMPANY, LTD.
10 * Copyright (C) 2016-2019 by TOPPERS PROJECT Educational Working Group.
11 *
12 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
20 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * の無保証規定を掲載すること.
22 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
23 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * と.
25 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
26 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
27 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * 報告すること.
29 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
30 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
32 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
33 * 免責すること.
34 *
35 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
36 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
37 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
38 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
39 * の責任を負わない.
40 *
41 * @(#) $Id$
42 */
43
44/*
45 * シリアルI/Oデバイス(SIO)ドライバ(stm32f7xx用)
46 */
47
48#include <kernel.h>
49#include <t_syslog.h>
50#include "target_stddef.h"
51#include "target_serial.h"
52#include "target_syssvc.h"
53
54/*
55 * レジスタ設定値
56 */
57#define PORT2SIOPID(x) ((x) + 1)
58#define INDEX_PORT(x) ((x) - 1)
59#define GET_SIOPCB(x) (&siopcb_table[INDEX_PORT(x)])
60
61/*
62 * GPIOモードパラメータ
63 */
64#define GPIO_MODE_INPUT 0x00000000 /* Input Floating Mode */
65#define GPIO_MODE_OUTPUT 0x00000001 /* Output Mode */
66#define GPIO_MODE_AF 0x00000002 /* Alternate Function Mode */
67#define GPIO_MODE_ANALOG 0x00000003 /* Analog Mode */
68
69/*
70 * GPIOアウトプット設定パラメータ
71 */
72#define GPIO_OTYPE_PP 0x0
73#define GPIO_OTYPE_OD 0x1
74
75/*
76 * GPIOアウトプット最大周波数パラメータ
77 */
78#define GPIO_SPEED_LOW 0x00000000 /* Low speed */
79#define GPIO_SPEED_MEDIUM 0x00000001 /* Medium speed */
80#define GPIO_SPEED_FAST 0x00000002 /* Fast speed */
81#define GPIO_SPEED_HIGH 0x00000003 /* High speed */
82
83/*
84 * GPIOプルアップダウンパラメータ
85 */
86#define GPIO_NOPULL 0x00000000 /* No Pull-up or Pull-down activation */
87#define GPIO_PULLUP 0x00000001 /* Pull-up activation */
88#define GPIO_PULLDOWN 0x00000002 /* Pull-down activation */
89
90/*
91 * CLOCKソース
92 */
93#define SOURCE_PCLK2 0
94#define SOURCE_SYSCLK 1
95#define SOURCE_HSI 2
96#define SOURCE_LSE 3
97
98/*
99 * ビット長パラメータ
100 */
101#define USART_WordLength_8b 0x0000
102#define USART_WordLength_9b USART_CR1_M
103
104/*
105 * ストップビットパラメータ
106 */
107#define USART_StopBits_1 0x0000
108#define USART_StopBits_0_5 USART_CR2_STOP_0
109#define USART_StopBits_2 USART_CR2_STOP_1
110#define USART_StopBits_1_5 USART_CR2_STOP
111
112/*
113 * パリティパラメータ
114 */
115#define USART_Parity_No 0x0000
116#define USART_Parity_Even USART_CR1_PCE
117#define USART_Parity_Odd (USART_CR1_PCE | USART_CR1_PS)
118
119/*
120 * ハードウェアフロー制御パラメータ
121 */
122#define USART_HardwareFlowControl_None 0x0000
123#define USART_HardwareFlowControl_RTS USART_CR3_RTSE
124#define USART_HardwareFlowControl_CTS USART_CR3_CTSE
125#define USART_HardwareFlowControl_RTS_CTS (USART_CR3_RTSE | USART_CR3_CTSE)
126
127#define ISR_ACK (USART_ISR_TEACK | USART_ISR_REACK)
128#define CR1_CLEAR_MASK (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8)
129#define CR3_CLEAR_MASK (USART_CR3_RTSE | USART_CR3_CTSE | USART_CR3_ONEBIT)
130
131#define UART_TIMEOUT_VALUE 0x1FFFFFF
132
133/*
134 * シリアルI/Oポート初期化ブロックの定義
135 */
136typedef struct sio_port_initialization_block {
137 uint32_t base;
138 INTNO intno_usart;
139 uint32_t clock_shift;
140} SIOPINIB;
141
142/*
143 * 兼用GPIOポート初期化ブロックの定義
144 */
145typedef struct gpio_port_initialization_block {
146 uint32_t clockbase;
147 uint32_t clock_set;
148 uint32_t portbase;
149 uint32_t txport_set;
150 uint32_t rxport_set;
151 uint32_t resetbase;
152 uint32_t reset_set;
153 uint32_t gpio_af;
154
155 uint32_t txportbase;
156 uint32_t txpinport;
157 uint32_t txmode_msk;
158 uint32_t txmode_set;
159 uint32_t txspeed_msk;
160 uint32_t txspeed_set;
161 uint32_t txtype_msk;
162 uint32_t txtype_set;
163 uint32_t txpupd_msk;
164 uint32_t txpupd_set;
165
166 uint32_t rxportbase;
167 uint32_t rxpinport;
168 uint32_t rxmode_msk;
169 uint32_t rxmode_set;
170 uint32_t rxspeed_msk;
171 uint32_t rxspeed_set;
172 uint32_t rxtype_msk;
173 uint32_t rxtype_set;
174 uint32_t rxpupd_msk;
175 uint32_t rxpupd_set;
176} GPIOINIB;
177
178/*
179 * シリアルI/Oポート管理ブロックの定義
180 */
181struct sio_port_control_block {
182 const SIOPINIB *p_siopinib; /* シリアルI/Oポート初期化ブロック */
183 const GPIOINIB *p_gpioinib; /* 兼用GPIOポート初期化ブロック */
184 intptr_t exinf; /* 拡張情報 */
185 bool_t opnflg; /* オープン済みフラグ */
186};
187
188/*
189 * シリアルI/Oポート初期化ブロック
190 */
191const SIOPINIB siopinib_table[TNUM_SIOP] = {
192 {(uint32_t)USART1_BASE, (INTNO)INTNO_SIO1, U1_CLOCK_SHIFT}
193#if TNUM_SIOP > 1
194 ,{(uint32_t)USART2_BASE, (INTNO)INTNO_SIO2, U2_CLOCK_SHIFT}
195#endif
196};
197
198/*
199 * 兼用GPIOポート初期化ブロック
200 */
201const GPIOINIB gpioinib_table[TNUM_SIOP] = {
202 {(uint32_t)(TADR_RCC_BASE+TOFF_U1_APBNER), (uint32_t)ENABLE_U1_PORT,
203 (uint32_t)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), (uint32_t)ENABLE_U1T_GPIO, (uint32_t)ENABLE_U1R_GPIO,
204 (uint32_t)(TADR_RCC_BASE+TOFF_U1_APBRSTR), (uint32_t)RESET_U1_PORT,
205 (uint32_t)GPIO_U1_AF,
206 (uint32_t)TADR_U1T_GPIO_BASE, (uint32_t)TX1_PINPOS,
207 (uint32_t)~(GPIO_MODER_MODER2 << (TX1_PINPOS*2)), (uint32_t)(GPIO_MODE_AF << (TX1_PINPOS*2)),
208 (uint32_t)~(GPIO_OSPEEDER_OSPEEDR2 << (TX1_PINPOS*2)), (uint32_t)(GPIO_SPEED_HIGH << (TX1_PINPOS*2)),
209 (uint32_t)~(GPIO_OTYPER_OT << TX1_PINPOS), (uint32_t)(GPIO_OTYPE_PP << TX1_PINPOS),
210 (uint32_t)~(GPIO_PUPDR_PUPDR2 << (TX1_PINPOS*2)), (uint32_t)(GPIO_PULLUP << (TX1_PINPOS*2)),
211 (uint32_t)TADR_U1R_GPIO_BASE, (uint32_t)RX1_PINPOS,
212 (uint32_t)~(GPIO_MODER_MODER2 << (RX1_PINPOS*2)), (uint32_t)(GPIO_MODE_AF << (RX1_PINPOS*2)),
213 (uint32_t)~(GPIO_OSPEEDER_OSPEEDR2 << (RX1_PINPOS*2)), (uint32_t)(GPIO_SPEED_HIGH << (RX1_PINPOS*2)),
214 (uint32_t)~(GPIO_OTYPER_OT << RX1_PINPOS), (uint32_t)(GPIO_MODE_AF << RX1_PINPOS),
215 (uint32_t)~(GPIO_PUPDR_PUPDR2 << (RX1_PINPOS*2)), (uint32_t)(GPIO_PULLUP << (RX1_PINPOS*2))
216 }
217#if TNUM_SIOP > 1
218 ,{(uint32_t)(TADR_RCC_BASE+TOFF_U2_APBNER), (uint32_t)ENABLE_U2_PORT,
219 (uint32_t)(TADR_RCC_BASE+TOFF_RCC_AHB1ENR), (uint32_t)ENABLE_U2T_GPIO, (uint32_t)ENABLE_U2R_GPIO,
220 (uint32_t)(TADR_RCC_BASE+TOFF_U2_APBRSTR), (uint32_t)RESET_U2_PORT,
221 (uint32_t)GPIO_U2_AF,
222 (uint32_t)TADR_U2T_GPIO_BASE, (uint32_t)TX2_PINPOS,
223 (uint32_t)~(GPIO_MODER_MODER2 << (TX2_PINPOS*2)), (uint32_t)(GPIO_MODE_AF << (TX2_PINPOS*2)),
224 (uint32_t)~(GPIO_OSPEEDER_OSPEEDR2 << (TX2_PINPOS*2)), (uint32_t)(GPIO_SPEED_HIGH << (TX2_PINPOS*2)),
225 (uint32_t)~(GPIO_OTYPER_OT << TX2_PINPOS), (uint32_t)(GPIO_OTYPE_PP << TX2_PINPOS),
226 (uint32_t)~(GPIO_PUPDR_PUPDR2 << (TX2_PINPOS*2)), (uint32_t)(GPIO_PULLUP << (TX2_PINPOS*2)),
227 (uint32_t)TADR_U2R_GPIO_BASE, (uint32_t)RX2_PINPOS,
228 (uint32_t)~(GPIO_MODER_MODER2 << (RX2_PINPOS*2)), (uint32_t)(GPIO_MODE_AF << (RX2_PINPOS*2)),
229 (uint32_t)~(GPIO_OSPEEDER_OSPEEDR2 << (RX2_PINPOS*2)), (uint32_t)(GPIO_SPEED_HIGH << (RX2_PINPOS*2)),
230 (uint32_t)~(GPIO_OTYPER_OT << RX2_PINPOS), (uint32_t)(GPIO_MODE_AF << RX2_PINPOS),
231 (uint32_t)~(GPIO_PUPDR_PUPDR2 << (RX2_PINPOS*2)), (uint32_t)(GPIO_PULLUP << (RX2_PINPOS*2))
232 }
233#endif
234};
235
236/*
237 * シリアルI/Oポート管理ブロックのエリア
238 */
239SIOPCB siopcb_table[TNUM_SIOP];
240
241/*
242 * シリアルI/OポートIDから管理ブロックを取り出すためのマクロ
243 */
244#define INDEX_SIOP(siopid) ((uint_t)((siopid) - 1))
245#define get_siopcb(siopid) (&(siopcb_table[INDEX_SIOP(siopid)]))
246
247static void setup_gpio_source(uint32_t base, uint8_t source, uint8_t select)
248{
249 uint32_t tmpreg, regoff;
250 regoff = TOFF_GPIO_AFR0+((source>>3) * 4);
251 tmpreg = (sil_rew_mem((uint32_t *)(base+regoff)) & ~(0xF << ((source & 0x07) * 4)))
252 | (select << ((source & 0x07) * 4));
253 sil_wrw_mem((uint32_t *)(base+regoff), tmpreg);
254}
255
256void put_hex(char a, int val)
257{
258 int i, j;
259 target_fput_log(a);
260 target_fput_log(' ');
261 for(i = 28 ; i >= 0 ; i-= 4){
262 j = (val >> i) & 0xf;;
263 if(j > 9)
264 j += ('A'-10);
265 else
266 j += '0';
267 target_fput_log(j);
268 }
269 target_fput_log('\n');
270}
271
272/*
273 * SIOドライバの初期化
274 */
275void
276sio_initialize(intptr_t exinf)
277{
278 SIOPCB *p_siopcb;
279 uint_t i;
280
281 /*
282 * シリアルI/Oポート管理ブロックの初期化
283 */
284 for (p_siopcb = siopcb_table, i = 0; i < TNUM_SIOP; p_siopcb++, i++) {
285 p_siopcb->p_siopinib = &(siopinib_table[i]);
286 p_siopcb->p_gpioinib = &(gpioinib_table[i]);
287 p_siopcb->opnflg = false;
288 }
289}
290
291/*
292 * シリアルI/Oポートのオープン
293 */
294SIOPCB *
295sio_opn_por(ID siopid, intptr_t exinf)
296{
297 SIOPCB *p_siopcb;
298 const SIOPINIB *p_siopinib;
299 const GPIOINIB *p_gpioinib;
300 bool_t opnflg;
301 ER ercd;
302 uint32_t base, txbase, rxbase, tmp;
303
304 p_siopcb = get_siopcb(siopid);
305 p_siopinib = p_siopcb->p_siopinib;
306 p_gpioinib = p_siopcb->p_gpioinib;
307
308 /*
309 * オープンしたポートがあるかをopnflgに読んでおく.
310 */
311 opnflg = p_siopcb->opnflg;
312
313 p_siopcb->exinf = exinf;
314 txbase = p_gpioinib->txportbase;
315 rxbase = p_gpioinib->rxportbase;
316 base = p_siopinib->base;
317
318 if(txbase == 0 || rxbase == 0) /* no usart port */
319 goto sio_opn_exit;
320
321 /*
322 * USART停止
323 */
324 sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), 0xFFFFFFFF);
325 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~USART_CR1_UE);
326
327 /*
328 * ハードウェアの初期化
329 */
330 if(p_siopinib->clock_shift == 0){ /* USART1の場合、SYSLOCKを設定 */
331 sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2),
332 (sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) & RCC_DCKCFGR2_USART1SEL) | RCC_DCKCFGR2_USART1SEL_0);
333 }
334 else if(p_siopinib->clock_shift == 10 && siopid == 1){ /* F723/USART6の場合、SYSLOCKを設定 */
335 sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2),
336 (sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) & RCC_DCKCFGR2_USART6SEL) | RCC_DCKCFGR2_USART6SEL_0);
337 }
338 sil_wrw_mem((uint32_t *)p_gpioinib->clockbase, sil_rew_mem((uint32_t *)p_gpioinib->clockbase) | p_gpioinib->clock_set);
339 sil_wrw_mem((uint32_t *)p_gpioinib->portbase, sil_rew_mem((uint32_t *)p_gpioinib->portbase) | p_gpioinib->txport_set);
340 sil_wrw_mem((uint32_t *)p_gpioinib->portbase, sil_rew_mem((uint32_t *)p_gpioinib->portbase) | p_gpioinib->rxport_set);
341 sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_MODER), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_MODER)) & p_gpioinib->txmode_msk) | p_gpioinib->txmode_set);
342 sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_OSPEEDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_OSPEEDR)) & p_gpioinib->txspeed_msk) | p_gpioinib->txspeed_set);
343 sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_OTYPER), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_OTYPER)) & p_gpioinib->txtype_msk) | p_gpioinib->txtype_set);
344 sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR)) & p_gpioinib->txpupd_msk) | p_gpioinib->txpupd_set);
345 sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_MODER), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_MODER)) & p_gpioinib->rxmode_msk) | p_gpioinib->rxmode_set);
346 sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_OSPEEDR), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_OSPEEDR)) & p_gpioinib->rxspeed_msk) | p_gpioinib->rxspeed_set);
347 sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_OTYPER), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_OTYPER)) & p_gpioinib->rxtype_msk) | p_gpioinib->rxtype_set);
348 sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_PUPDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR)) & p_gpioinib->rxpupd_msk) | p_gpioinib->rxpupd_set);
349 setup_gpio_source(txbase, p_gpioinib->txpinport, p_gpioinib->gpio_af);
350 setup_gpio_source(rxbase, p_gpioinib->rxpinport, p_gpioinib->gpio_af);
351
352 tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR2)) & ~USART_CR2_STOP;
353 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR2), tmp | USART_StopBits_1);
354 tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~CR1_CLEAR_MASK;
355 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), tmp | USART_WordLength_8b | USART_Parity_No | USART_CR1_RE | USART_CR1_TE);
356 tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3)) & ~CR3_CLEAR_MASK;
357 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), tmp | USART_HardwareFlowControl_None);
358
359 switch((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) >> p_siopinib->clock_shift) & 3){
360 case SOURCE_HSI:
361 tmp = HSI_VALUE;
362 break;
363 case SOURCE_SYSCLK:
364 tmp = SysFreHCLK;
365 break;
366 case SOURCE_LSE:
367 tmp = LSE_VALUE;
368 break;
369 case SOURCE_PCLK2:
370 default:
371 if(p_siopinib->clock_shift == 10) /* USART6,1の場合 PCLK2 */
372 tmp = SysFrePCLK2;
373 else
374 tmp = SysFrePCLK1;
375 break;
376 }
377 sil_wrw_mem((uint32_t *)(base+TOFF_USART_BRR), tmp/BPS_SETTING);
378 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR2), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR2)) & ~(USART_CR2_LINEN | USART_CR2_CLKEN));
379 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3)) & ~(USART_CR3_SCEN | USART_CR3_HDSEL | USART_CR3_IREN));
380
381 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_UE);
382
383 /*
384 * RX/TX ACKがセットされるまで待つ
385 */
386 tmp = 0;
387 while((sil_rew_mem((uint32_t *)(base+TOFF_USART_ISR)) & ISR_ACK) != ISR_ACK){
388 /* Check for the Timeout */
389 if(tmp >= UART_TIMEOUT_VALUE){
390 /* Disable TXE, RXNE, PE and ERR (Frame error, noise error, overrun error) interrupts for the interrupt process */
391 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1),
392 sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~(USART_CR1_TXEIE | USART_CR1_RXNEIE | USART_CR1_PEIE));
393 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3),
394 sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3)) & ~USART_CR3_EIE);
395 goto sio_opn_exit;
396 }
397 sil_dly_nse(1000);
398 tmp++;
399 }
400
401 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_PEIE);
402 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3)) | USART_CR3_EIE);
403 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_RXNEIE);
404 p_siopcb->opnflg = true;
405
406 /*
407 * シリアルI/O割込みのマスクを解除する.
408 */
409 if (!opnflg) {
410 ercd = ena_int(p_siopinib->intno_usart);
411 assert(ercd == E_OK);
412 }
413
414sio_opn_exit:;
415 return(p_siopcb);
416}
417
418/*
419 * シリアルI/Oポートのクローズ
420 */
421void
422sio_cls_por(SIOPCB *p_siopcb)
423{
424 const SIOPINIB *p_siopinib;
425 const GPIOINIB *p_gpioinib;
426 uint32_t base, tmp;
427
428 /*
429 * シリアルI/O割込みをマスクする.
430 */
431 if ((p_siopcb->opnflg)) {
432 dis_int(p_siopcb->p_siopinib->intno_usart);
433 }
434
435 /*
436 * ハードウェアのリセット
437 */
438 p_siopinib = p_siopcb->p_siopinib;
439 p_gpioinib = p_siopcb->p_gpioinib;
440 base = p_siopinib->base;
441 sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), 0xFFFFFFFF);
442 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~USART_CR1_UE);
443 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), 0x0);
444 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR2), 0x0);
445 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), 0x0);
446 tmp = sil_rew_mem((uint32_t *)p_gpioinib->resetbase);
447 sil_wrw_mem((uint32_t *)p_gpioinib->resetbase, tmp | p_gpioinib->reset_set);
448 sil_wrw_mem((uint32_t *)p_gpioinib->resetbase, tmp & ~(p_gpioinib->reset_set));
449 p_siopcb->opnflg = false;
450}
451
452/*
453 * SIOの割込みサービスルーチン
454 */
455
456Inline bool_t
457sio_putready(SIOPCB* p_siopcb)
458{
459 uint32_t cr1 = sil_rew_mem((uint32_t *)(p_siopcb->p_siopinib->base+TOFF_USART_CR1));
460 uint32_t isr = sil_rew_mem((uint32_t *)(p_siopcb->p_siopinib->base+TOFF_USART_ISR));
461
462 if ((cr1 & USART_CR1_TXEIE) != 0 && (isr & USART_ISR_TXE) != 0)
463 {
464 return 1;
465 }
466 return 0;
467}
468
469Inline bool_t
470sio_getready(SIOPCB* p_siopcb)
471{
472 uint32_t base = p_siopcb->p_siopinib->base;
473 uint32_t cr1, cr3, isr;
474
475 cr1 = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1));
476 cr3 = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3));
477 isr = sil_rew_mem((uint32_t *)(base+TOFF_USART_ISR));
478
479 if((isr & USART_ISR_PE) != 0 && (cr3 & USART_CR3_EIE) != 0){
480 sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), USART_ICR_PECF);
481 }
482 if((isr & USART_ISR_FE) != 0 && (cr3 & USART_CR3_EIE) != 0){
483 sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), USART_ICR_FECF);
484 }
485 if((isr & USART_ISR_NE) != 0 && (cr3 & USART_CR3_EIE) != 0){
486 sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), USART_ICR_NCF);
487 }
488 if((isr & USART_ISR_ORE) != 0 && (cr3 & USART_CR3_EIE) != 0){
489 sil_wrw_mem((uint32_t *)(base+TOFF_USART_ICR), USART_ICR_ORECF);
490 }
491 if ((cr1 & USART_CR1_RXNEIE) != 0 && (isr & USART_ISR_RXNE) != 0)
492 {
493 return 1;
494 }
495 return 0;
496}
497
498void
499sio_usart_isr(intptr_t exinf)
500{
501 if ((exinf <= 0) || (exinf > TNUM_SIOP))
502 return;
503
504 SIOPCB *p_siopcb = get_siopcb(exinf);
505 if (!p_siopcb->opnflg)
506 return;
507
508 if (sio_getready(p_siopcb)) {
509 sio_irdy_rcv(p_siopcb->exinf);
510 }
511 if (sio_putready(p_siopcb)) {
512 sio_irdy_snd(p_siopcb->exinf);
513 }
514}
515
516/*
517 * シリアルI/Oポートへの文字送信
518 */
519bool_t
520sio_snd_chr(SIOPCB *p_siopcb, char c)
521{
522 uint32_t base = p_siopcb->p_siopinib->base;
523
524 if (sio_putready(p_siopcb)) {
525 sil_wrw_mem((uint32_t *)(base+TOFF_USART_TDR), (uint32_t)c);
526 return true;
527 }
528 return false;
529}
530
531/*
532 * シリアルI/Oポートからの文字受信
533 */
534int_t
535sio_rcv_chr(SIOPCB *p_siopcb)
536{
537 uint32_t base = p_siopcb->p_siopinib->base;
538 int_t c = -1;
539
540 if (sio_getready(p_siopcb)) {
541 c = sil_rew_mem((uint32_t *)(base+TOFF_USART_RDR)) & 0xFF;
542 }
543 return c;
544}
545
546/*
547 * シリアルI/Oポートからのコールバックの許可
548 */
549void
550sio_ena_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
551{
552 uint32_t base = p_siopcb->p_siopinib->base;
553
554 switch (cbrtn) {
555 case SIO_RDY_SND:
556 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_TXEIE);
557 break;
558 case SIO_RDY_RCV:
559 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_RXNEIE);
560 break;
561 }
562}
563
564/*
565 * シリアルI/Oポートからのコールバックの禁止
566 */
567void
568sio_dis_cbr(SIOPCB *p_siopcb, uint_t cbrtn)
569{
570 uint32_t base = p_siopcb->p_siopinib->base;
571
572 switch (cbrtn) {
573 case SIO_RDY_SND:
574 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~USART_CR1_TXEIE);
575 break;
576 case SIO_RDY_RCV:
577 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~USART_CR1_RXNEIE);
578 break;
579 }
580}
581
582/*
583 * 1文字出力(ポーリングでの出力)
584 */
585void sio_pol_snd_chr(int8_t c, ID siopid)
586{
587 uint32_t base = siopinib_table[INDEX_PORT(siopid)].base;
588
589 sil_wrw_mem((uint32_t *)(base+TOFF_USART_TDR), (uint32_t)c);
590 while(0 == (sil_rew_mem((uint32_t *)(base+TOFF_USART_ISR)) & USART_ISR_TXE));
591
592 /*
593 * 出力が完全に終わるまで待つ
594 */
595 volatile int n = 300000000/BPS_SETTING;
596 while(n--);
597}
598
599/*
600 * ターゲットのシリアル初期化
601 */
602void chip_uart_init(ID siopid)
603{
604 const GPIOINIB *p_gpioinib = &gpioinib_table[INDEX_PORT(siopid)];
605 const SIOPINIB *p_siopinib = &siopinib_table[INDEX_PORT(siopid)];
606 uint32_t base, txbase, rxbase, tmp;
607
608 txbase = p_gpioinib->txportbase;
609 rxbase = p_gpioinib->rxportbase;
610 base = p_siopinib->base;
611
612 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~USART_CR1_UE);
613 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), 0x0);
614 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR2), 0x0);
615 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), 0x0);
616 tmp = sil_rew_mem((uint32_t *)p_gpioinib->resetbase);
617 sil_wrw_mem((uint32_t *)p_gpioinib->resetbase, tmp | p_gpioinib->reset_set);
618 sil_wrw_mem((uint32_t *)p_gpioinib->resetbase, tmp & ~(p_gpioinib->reset_set));
619
620 if(p_siopinib->clock_shift == 0){ /* USART1の場合、SYSLOCKを設定 */
621 sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2),
622 (sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) & RCC_DCKCFGR2_USART1SEL) | RCC_DCKCFGR2_USART1SEL_0);
623 }
624 else if(p_siopinib->clock_shift == 10){ /* F723/USART6の場合、SYSLOCKを設定 */
625 sil_wrw_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2),
626 (sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) & RCC_DCKCFGR2_USART6SEL) | RCC_DCKCFGR2_USART6SEL_0);
627 }
628
629 sil_wrw_mem((uint32_t *)p_gpioinib->clockbase, sil_rew_mem((uint32_t *)p_gpioinib->clockbase) | p_gpioinib->clock_set);
630 sil_wrw_mem((uint32_t *)p_gpioinib->portbase, sil_rew_mem((uint32_t *)p_gpioinib->portbase) | p_gpioinib->txport_set);
631 sil_wrw_mem((uint32_t *)p_gpioinib->portbase, sil_rew_mem((uint32_t *)p_gpioinib->portbase) | p_gpioinib->rxport_set);
632 sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_MODER), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_MODER)) & p_gpioinib->txmode_msk) | p_gpioinib->txmode_set);
633 sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_OSPEEDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_OSPEEDR)) & p_gpioinib->txspeed_msk) | p_gpioinib->txspeed_set);
634 sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_OTYPER), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_OTYPER)) & p_gpioinib->txtype_msk) | p_gpioinib->txtype_set);
635 sil_wrw_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR)) & p_gpioinib->txpupd_msk) | p_gpioinib->txpupd_set);
636 sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_MODER), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_MODER)) & p_gpioinib->rxmode_msk) | p_gpioinib->rxmode_set);
637 sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_OSPEEDR), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_OSPEEDR)) & p_gpioinib->rxspeed_msk) | p_gpioinib->rxspeed_set);
638 sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_OTYPER), (sil_rew_mem((uint32_t *)(rxbase+TOFF_GPIO_OTYPER)) & p_gpioinib->rxtype_msk) | p_gpioinib->rxtype_set);
639 sil_wrw_mem((uint32_t *)(rxbase+TOFF_GPIO_PUPDR), (sil_rew_mem((uint32_t *)(txbase+TOFF_GPIO_PUPDR)) & p_gpioinib->rxpupd_msk) | p_gpioinib->rxpupd_set);
640 setup_gpio_source(txbase, p_gpioinib->txpinport, p_gpioinib->gpio_af);
641 setup_gpio_source(rxbase, p_gpioinib->rxpinport, p_gpioinib->gpio_af);
642
643 tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR2)) & ~USART_CR2_STOP;
644 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR2), tmp | USART_StopBits_1);
645 tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) & ~CR1_CLEAR_MASK;
646 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), tmp | USART_WordLength_8b | USART_Parity_No | USART_CR1_RE | USART_CR1_TE);
647 tmp = sil_rew_mem((uint32_t *)(base+TOFF_USART_CR3)) & ~CR3_CLEAR_MASK;
648 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR3), tmp | USART_HardwareFlowControl_None);
649
650 switch((sil_rew_mem((uint32_t *)(TADR_RCC_BASE+TOFF_RCC_DCKCFGR2)) >> p_siopinib->clock_shift) & 3){
651 case SOURCE_HSI:
652 tmp = HSI_VALUE;
653 break;
654 case SOURCE_SYSCLK:
655 tmp = SysFreHCLK;
656 break;
657 case SOURCE_LSE:
658 tmp = LSE_VALUE;
659 break;
660 case SOURCE_PCLK2:
661 default:
662 if(p_siopinib->clock_shift == 10) /* USART6,1の場合 PCLK2 */
663 tmp = SysFrePCLK2;
664 else
665 tmp = SysFrePCLK1;
666 break;
667 }
668 sil_wrw_mem((uint32_t *)(base+TOFF_USART_BRR), tmp/BPS_SETTING);
669 sil_wrw_mem((uint32_t *)(base+TOFF_USART_CR1), sil_rew_mem((uint32_t *)(base+TOFF_USART_CR1)) | USART_CR1_UE);
670}
671
Note: See TracBrowser for help on using the repository browser.