Contiki 2.5
debug-uart.c
1 #include <debug-uart.h>
2 #include <string.h>
3 #include <stm32f10x_map.h>
4 #include <stm32f10x_dma.h>
5 #include <gpio.h>
6 #include <nvic.h>
7 
8 #ifndef DBG_UART
9 #define DBG_UART USART1
10 #endif
11 
12 #ifndef DBG_DMA_NO
13 #define DBG_DMA_NO 1
14 #endif
15 
16 #ifndef DBG_DMA_CHANNEL_NO
17 #define DBG_DMA_CHANNEL_NO 4
18 #endif
19 
20 
21 #define _DBG_DMA_NAME(x) DMA##x
22 #define DBG_DMA_NAME(x) _DBG_DMA_NAME(x)
23 #define DBG_DMA DBG_DMA_NAME(DBG_DMA_NO)
24 
25 #define _DMA_CHANNEL_NAME(x,c) DMA ## x ## _Channel ## c
26 #define DMA_CHANNEL_NAME(x,c) _DMA_CHANNEL_NAME(x,c)
27 #define DBG_DMA_CHANNEL DMA_CHANNEL_NAME(DBG_DMA_NO, DBG_DMA_CHANNEL_NO)
28 
29 #define _DBG_DMA_CHANNEL_IFCR_CGIF(c) DMA_IFCR_CGIF ## c
30 #define _XDBG_DMA_CHANNEL_IFCR_CGIF(c) _DBG_DMA_CHANNEL_IFCR_CGIF(c)
31 #define DBG_DMA_CHANNEL_IFCR_CGIF \
32 _XDBG_DMA_CHANNEL_IFCR_CGIF(DBG_DMA_CHANNEL_NO)
33 
34 
35 #ifndef DBG_XMIT_BUFFER_LEN
36 #define DBG_XMIT_BUFFER_LEN 1024
37 #endif
38 
39 
40 static unsigned char xmit_buffer[DBG_XMIT_BUFFER_LEN];
41 #define XMIT_BUFFER_END &xmit_buffer[DBG_XMIT_BUFFER_LEN]
42 void
43 dbg_setup_uart_default()
44 {
45  RCC->APB2ENR |= (RCC_APB2ENR_AFIOEN
46  | RCC_APB2ENR_IOPAEN| RCC_APB2ENR_IOPBEN
47  | RCC_APB2ENR_USART1EN );
48  RCC->AHBENR |= RCC_AHBENR_DMA1EN;
49  AFIO_REMAP( AFIO_MAPR_USART1_REMAP, AFIO_MAPR_USART1_REMAP);
50  GPIO_CONF_OUTPUT_PORT(B,6,ALT_PUSH_PULL,50);
51  GPIO_CONF_INPUT_PORT(B,7,FLOATING);
52 
53  USART1->CR1 = USART_CR1_UE;
54 
55  USART1->CR2 = 0;
56  USART1->CR3 = USART_CR3_DMAT;
57  USART1->CR1 |= USART_CR1_TE;
58  USART1->BRR= 0x1a1;
59 }
60 
61 /* Valid data in head to tail-1 */
62 /* Read position */
63 static unsigned char * volatile xmit_buffer_head = xmit_buffer;
64 
65 /* Write position */
66 static unsigned char * volatile xmit_buffer_tail = xmit_buffer;
67 
68 /* xmit_buffer_head == xmit_buffer_tail means empty so we can only store
69  DBG_XMIT_BUFFER_LEN-1 characters */
70 
71 volatile unsigned char dma_running = 0;
72 static unsigned char * volatile dma_end;
73 void
74 DMA1_Channel4_handler() __attribute__((interrupt));
75 
76 
77 static void
78 update_dma(void)
79 {
80  if (xmit_buffer_tail == xmit_buffer_head) return;
81  DBG_DMA_CHANNEL->CCR = (DMA_Priority_Low |
82  DMA_PeripheralDataSize_Byte |
83  DMA_MemoryDataSize_Byte |
84  DMA_PeripheralInc_Disable |
85  DMA_MemoryInc_Enable |
86  DMA_Mode_Normal |
87  DMA_DIR_PeripheralDST |
88  DMA_CCR4_TCIE
89  );
90  DBG_DMA_CHANNEL->CPAR = (u32)&DBG_UART->DR;
91  DBG_DMA_CHANNEL->CMAR = (u32)xmit_buffer_head;
92  if (xmit_buffer_head < xmit_buffer_tail) {
93  DBG_DMA_CHANNEL->CNDTR = xmit_buffer_tail - xmit_buffer_head;
94  dma_end = xmit_buffer_tail;
95  } else {
96  DBG_DMA_CHANNEL->CNDTR = XMIT_BUFFER_END - xmit_buffer_head;
97  dma_end = xmit_buffer;
98  }
99  NVIC_ENABLE_INT(DMA1_Channel4_IRQChannel);
100  NVIC_SET_PRIORITY(DMA1_Channel4_IRQChannel, 2);
101  DBG_DMA_CHANNEL->CCR |=DMA_CCR4_EN;
102 }
103 
104 
105 
106 void
107 DMA1_Channel4_handler()
108 {
109  DBG_DMA->IFCR = DBG_DMA_CHANNEL_IFCR_CGIF;
110  xmit_buffer_head = dma_end;
111  if (xmit_buffer_tail == xmit_buffer_head) {
112  dma_running = 0;
113  return;
114  }
115  update_dma();
116 }
117 
118 unsigned int
119 dbg_send_bytes(const unsigned char *seq, unsigned int len)
120 {
121  /* Since each of the pointers should be read atomically
122  there's no need to disable interrupts */
123  unsigned char *head = xmit_buffer_head;
124  unsigned char *tail = xmit_buffer_tail;
125  if (tail >= head) {
126  /* Free space wraps */
127  unsigned int xfer_len = XMIT_BUFFER_END - tail;
128  unsigned int free = DBG_XMIT_BUFFER_LEN - (tail - head) - 1;
129  if (len > free) len = free;
130  if (xfer_len < len) {
131  memcpy(tail, seq, xfer_len);
132  seq += xfer_len;
133  xfer_len = len - xfer_len;
134  memcpy(xmit_buffer, seq, xfer_len);
135  tail = xmit_buffer + xfer_len;
136  } else {
137  memcpy(tail, seq, len);
138  tail += len;
139  if (tail == XMIT_BUFFER_END) tail = xmit_buffer;
140  }
141  } else {
142  /* Free space continuous */
143  unsigned int free = (head - tail) - 1;
144  if (len > free) len = free;
145  memcpy(tail, seq, len);
146  tail += len;
147  }
148  xmit_buffer_tail = tail;
149  if (!dma_running) {
150  dma_running = 1;
151  update_dma();
152  }
153  return len;
154 }
155 
156 static unsigned char dbg_write_overrun = 0;
157 
158 void
159 dbg_putchar(const char ch)
160 {
161  if (dbg_write_overrun) {
162  if (dbg_send_bytes((const unsigned char*)"^",1) != 1) return;
163  }
164  dbg_write_overrun = 0;
165  if (dbg_send_bytes((const unsigned char*)&ch,1) != 1) {
166  dbg_write_overrun = 1;
167  }
168 }
169 
170 void
171 dbg_blocking_putchar(const char ch)
172 {
173  if (dbg_write_overrun) {
174  while (dbg_send_bytes((const unsigned char*)"^",1) != 1);
175  }
176  dbg_write_overrun = 0;
177  while (dbg_send_bytes((const unsigned char*)&ch,1) != 1);
178 }
179 
180 void
181 dbg_drain()
182 {
183  while(xmit_buffer_tail != xmit_buffer_head);
184 }