Project

General

Profile

Download (3.31 KB) Statistics
| Branch: | Tag: | Revision:
1
/* Buffered USB debug output
2
 * (C) 2007 Henryk Plötz <henryk@ploetzli.ch>
3
 *
4
 *  This program is free software; you can redistribute it and/or modify
5
 *  it under the terms of the GNU General Public License as published by 
6
 *  the Free Software Foundation; either version 2 of the License, or
7
 *  (at your option) any later version.
8
 *
9
 *  This program is distributed in the hope that it will be useful,
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 *  GNU General Public License for more details.
13
 *
14
 *  You should have received a copy of the GNU General Public License
15
 *  along with this program; if not, write to the Free Software
16
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 *
18
 */
19

    
20
#include <FreeRTOS.h>
21
#include <task.h> 
22
#include <semphr.h>
23
#include <USB-CDC.h>
24
#include <string.h>
25

    
26
#include "usb_print.h"
27

    
28
#define BUFLEN (2*1024)
29

    
30
static char ringbuffer[BUFLEN];
31
static int ringstart, ringstop;
32
static int default_flush = 1, forced_silence = 0;
33
static xSemaphoreHandle print_semaphore;
34

    
35
void usb_print_buffer(const char* buffer, int start, int stop) {
36
	usb_print_buffer_f(buffer,start,stop,default_flush);
37
}
38
int usb_print_buffer_f(const char* buffer, int start, int stop, int flush)
39
{
40
	int pos=start, endpos=stop;
41
	while(pos<stop) {
42
		int available = BUFLEN-1 - (((ringstop+BUFLEN)-ringstart) % BUFLEN);
43
		if(available == 0 && flush) { 
44
			usb_print_flush();
45
			continue;
46
		}
47
		if((endpos-pos)>available) endpos=pos+available;
48
		
49
		while(pos < endpos) {
50
			ringbuffer[ringstop] = buffer[pos];
51
			pos++;
52
			available--;
53
			ringstop = (ringstop+1) % BUFLEN;
54
		}
55
		
56
		if(flush) usb_print_flush();
57
		else if(available==0)
58
			return 0;
59
		endpos=stop;
60
		if(pos>=stop)
61
			return (available > 0);
62
	}
63
	return 0;
64
}
65

    
66
void usb_print_string(const char *string) {
67
	usb_print_string_f(string, default_flush);
68
}
69
int usb_print_string_f(const char* string, int flush)
70
{
71
	int start = 0, stop = strlen(string);
72
	return usb_print_buffer_f(string, start, stop, flush);
73
}
74

    
75
void usb_print_char(const char c) {
76
	usb_print_char_f(c, default_flush);
77
}
78
int usb_print_char_f(const char c, int flush)
79
{
80
	return usb_print_buffer_f(&c, 0, 1, flush);
81
}
82

    
83
int usb_print_get_default_flush(void)
84
{
85
	return default_flush;
86
}
87

    
88
int usb_print_set_default_flush(int flush)
89
{
90
	int old_flush = default_flush;
91
	default_flush = flush;
92
	return old_flush;
93
}
94

    
95
int usb_print_set_force_silence(int silence)
96
{
97
	int old_silence = forced_silence;
98
	forced_silence = silence;
99
	return old_silence;
100
}
101

    
102

    
103
/* Must NOT be called from ISR context */
104
void usb_print_flush(void)
105
{
106
	int oldstop, newstart;
107
	if(forced_silence) return;
108
	
109
	taskENTER_CRITICAL();
110
	if(print_semaphore == NULL)
111
		usb_print_init();
112
	if(print_semaphore == NULL) {
113
		taskEXIT_CRITICAL();
114
		return;
115
	}
116
	taskEXIT_CRITICAL();
117
	
118
	xSemaphoreTake(print_semaphore, portMAX_DELAY);
119
	
120
	taskENTER_CRITICAL();
121
	oldstop = ringstop;
122
	newstart = ringstart;
123
	taskEXIT_CRITICAL();
124
	 
125
	while(newstart != oldstop) {
126
		vUSBSendByte_blocking(ringbuffer[newstart], 5*portTICK_RATE_MS);
127
		newstart = (newstart+1) % BUFLEN;
128
	}
129
	
130
	taskENTER_CRITICAL();
131
	ringstart = newstart;
132
	taskEXIT_CRITICAL();
133
	
134
	xSemaphoreGive(print_semaphore);
135
}
136

    
137
void usb_print_init(void)
138
{
139
	memset(ringbuffer, 0, BUFLEN);
140
	ringstart = ringstop = 0;
141
	vSemaphoreCreateBinary( print_semaphore );
142
}
(58-58/59)
Add picture from clipboard (Maximum size: 48.8 MB)