Contiki 2.6
|
00001 #include <debug-uart.h> 00002 #include <string.h> 00003 #include <stm32f10x_map.h> 00004 #include <stm32f10x_dma.h> 00005 #include <gpio.h> 00006 #include <nvic.h> 00007 00008 #ifndef DBG_UART 00009 #define DBG_UART USART1 00010 #endif 00011 00012 #ifndef DBG_DMA_NO 00013 #define DBG_DMA_NO 1 00014 #endif 00015 00016 #ifndef DBG_DMA_CHANNEL_NO 00017 #define DBG_DMA_CHANNEL_NO 4 00018 #endif 00019 00020 00021 #define _DBG_DMA_NAME(x) DMA##x 00022 #define DBG_DMA_NAME(x) _DBG_DMA_NAME(x) 00023 #define DBG_DMA DBG_DMA_NAME(DBG_DMA_NO) 00024 00025 #define _DMA_CHANNEL_NAME(x,c) DMA ## x ## _Channel ## c 00026 #define DMA_CHANNEL_NAME(x,c) _DMA_CHANNEL_NAME(x,c) 00027 #define DBG_DMA_CHANNEL DMA_CHANNEL_NAME(DBG_DMA_NO, DBG_DMA_CHANNEL_NO) 00028 00029 #define _DBG_DMA_CHANNEL_IFCR_CGIF(c) DMA_IFCR_CGIF ## c 00030 #define _XDBG_DMA_CHANNEL_IFCR_CGIF(c) _DBG_DMA_CHANNEL_IFCR_CGIF(c) 00031 #define DBG_DMA_CHANNEL_IFCR_CGIF \ 00032 _XDBG_DMA_CHANNEL_IFCR_CGIF(DBG_DMA_CHANNEL_NO) 00033 00034 00035 #ifndef DBG_XMIT_BUFFER_LEN 00036 #define DBG_XMIT_BUFFER_LEN 1024 00037 #endif 00038 00039 00040 static unsigned char xmit_buffer[DBG_XMIT_BUFFER_LEN]; 00041 #define XMIT_BUFFER_END &xmit_buffer[DBG_XMIT_BUFFER_LEN] 00042 void 00043 dbg_setup_uart_default() 00044 { 00045 RCC->APB2ENR |= (RCC_APB2ENR_AFIOEN 00046 | RCC_APB2ENR_IOPAEN| RCC_APB2ENR_IOPBEN 00047 | RCC_APB2ENR_USART1EN ); 00048 RCC->AHBENR |= RCC_AHBENR_DMA1EN; 00049 AFIO_REMAP( AFIO_MAPR_USART1_REMAP, AFIO_MAPR_USART1_REMAP); 00050 GPIO_CONF_OUTPUT_PORT(B,6,ALT_PUSH_PULL,50); 00051 GPIO_CONF_INPUT_PORT(B,7,FLOATING); 00052 00053 USART1->CR1 = USART_CR1_UE; 00054 00055 USART1->CR2 = 0; 00056 USART1->CR3 = USART_CR3_DMAT; 00057 USART1->CR1 |= USART_CR1_TE; 00058 USART1->BRR= 0x1a1; 00059 } 00060 00061 /* Valid data in head to tail-1 */ 00062 /* Read position */ 00063 static unsigned char * volatile xmit_buffer_head = xmit_buffer; 00064 00065 /* Write position */ 00066 static unsigned char * volatile xmit_buffer_tail = xmit_buffer; 00067 00068 /* xmit_buffer_head == xmit_buffer_tail means empty so we can only store 00069 DBG_XMIT_BUFFER_LEN-1 characters */ 00070 00071 volatile unsigned char dma_running = 0; 00072 static unsigned char * volatile dma_end; 00073 void 00074 DMA1_Channel4_handler() __attribute__((interrupt)); 00075 00076 00077 static void 00078 update_dma(void) 00079 { 00080 if (xmit_buffer_tail == xmit_buffer_head) return; 00081 DBG_DMA_CHANNEL->CCR = (DMA_Priority_Low | 00082 DMA_PeripheralDataSize_Byte | 00083 DMA_MemoryDataSize_Byte | 00084 DMA_PeripheralInc_Disable | 00085 DMA_MemoryInc_Enable | 00086 DMA_Mode_Normal | 00087 DMA_DIR_PeripheralDST | 00088 DMA_CCR4_TCIE 00089 ); 00090 DBG_DMA_CHANNEL->CPAR = (u32)&DBG_UART->DR; 00091 DBG_DMA_CHANNEL->CMAR = (u32)xmit_buffer_head; 00092 if (xmit_buffer_head < xmit_buffer_tail) { 00093 DBG_DMA_CHANNEL->CNDTR = xmit_buffer_tail - xmit_buffer_head; 00094 dma_end = xmit_buffer_tail; 00095 } else { 00096 DBG_DMA_CHANNEL->CNDTR = XMIT_BUFFER_END - xmit_buffer_head; 00097 dma_end = xmit_buffer; 00098 } 00099 NVIC_ENABLE_INT(DMA1_Channel4_IRQChannel); 00100 NVIC_SET_PRIORITY(DMA1_Channel4_IRQChannel, 2); 00101 DBG_DMA_CHANNEL->CCR |=DMA_CCR4_EN; 00102 } 00103 00104 00105 00106 void 00107 DMA1_Channel4_handler() 00108 { 00109 DBG_DMA->IFCR = DBG_DMA_CHANNEL_IFCR_CGIF; 00110 xmit_buffer_head = dma_end; 00111 if (xmit_buffer_tail == xmit_buffer_head) { 00112 dma_running = 0; 00113 return; 00114 } 00115 update_dma(); 00116 } 00117 00118 unsigned int 00119 dbg_send_bytes(const unsigned char *seq, unsigned int len) 00120 { 00121 /* Since each of the pointers should be read atomically 00122 there's no need to disable interrupts */ 00123 unsigned char *head = xmit_buffer_head; 00124 unsigned char *tail = xmit_buffer_tail; 00125 if (tail >= head) { 00126 /* Free space wraps */ 00127 unsigned int xfer_len = XMIT_BUFFER_END - tail; 00128 unsigned int free = DBG_XMIT_BUFFER_LEN - (tail - head) - 1; 00129 if (len > free) len = free; 00130 if (xfer_len < len) { 00131 memcpy(tail, seq, xfer_len); 00132 seq += xfer_len; 00133 xfer_len = len - xfer_len; 00134 memcpy(xmit_buffer, seq, xfer_len); 00135 tail = xmit_buffer + xfer_len; 00136 } else { 00137 memcpy(tail, seq, len); 00138 tail += len; 00139 if (tail == XMIT_BUFFER_END) tail = xmit_buffer; 00140 } 00141 } else { 00142 /* Free space continuous */ 00143 unsigned int free = (head - tail) - 1; 00144 if (len > free) len = free; 00145 memcpy(tail, seq, len); 00146 tail += len; 00147 } 00148 xmit_buffer_tail = tail; 00149 if (!dma_running) { 00150 dma_running = 1; 00151 update_dma(); 00152 } 00153 return len; 00154 } 00155 00156 static unsigned char dbg_write_overrun = 0; 00157 00158 void 00159 dbg_putchar(const char ch) 00160 { 00161 if (dbg_write_overrun) { 00162 if (dbg_send_bytes((const unsigned char*)"^",1) != 1) return; 00163 } 00164 dbg_write_overrun = 0; 00165 if (dbg_send_bytes((const unsigned char*)&ch,1) != 1) { 00166 dbg_write_overrun = 1; 00167 } 00168 } 00169 00170 void 00171 dbg_blocking_putchar(const char ch) 00172 { 00173 if (dbg_write_overrun) { 00174 while (dbg_send_bytes((const unsigned char*)"^",1) != 1); 00175 } 00176 dbg_write_overrun = 0; 00177 while (dbg_send_bytes((const unsigned char*)&ch,1) != 1); 00178 } 00179 00180 void 00181 dbg_drain() 00182 { 00183 while(xmit_buffer_tail != xmit_buffer_head); 00184 }