Project

General

Profile

Download (12.2 KB) Statistics
| Branch: | Tag: | Revision:
1
/* ----------------------------------------------------------------------------
2
 *         ATMEL Microcontroller Software Support
3
 * ----------------------------------------------------------------------------
4
 * Copyright (c) 2009, Atmel Corporation
5
 *
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions are met:
10
 *
11
 * - Redistributions of source code must retain the above copyright notice,
12
 * this list of conditions and the disclaimer below.
13
 *
14
 * Atmel's name may not be used to endorse or promote products derived from
15
 * this software without specific prior written permission.
16
 *
17
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 * ----------------------------------------------------------------------------
28
 */
29
/**
30
 *  \file
31
 *
32
 *  This file contains all the specific code for the
33
 *  usb_fast_source example.
34
 */
35

    
36
/*----------------------------------------------------------------------------
37
 *         Headers
38
 *----------------------------------------------------------------------------*/
39

    
40
#include <board.h>
41

    
42
#include <stdio.h>
43
#include <string.h>
44
#include <errno.h>
45
#include <stdint.h>
46
#include <stdbool.h>
47
#include <stdbool.h>
48

    
49
#include <irq/irq.h>
50
#include <pio/pio.h>
51
#include <pio/pio_it.h>
52
#include <utility/trace.h>
53
#include <utility/led.h>
54

    
55
#include <memories/flash/flashd.h>
56

    
57
#include <peripherals/rstc/rstc.h>
58

    
59
#include <usb/device/core/USBD.h>
60
#include <usb/device/core/USBDDriver.h>
61
#include <usb/device/dfu/dfu.h>
62

    
63
#include "dfu_desc.h"
64

    
65
#include "opcode.h"
66

    
67
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
68

    
69
/*----------------------------------------------------------------------------
70
 *         Definitions
71
 *----------------------------------------------------------------------------*/
72

    
73
/// Use for power management
74
#define STATE_IDLE    0
75
/// The USB device is in suspend state
76
#define STATE_SUSPEND 4
77
/// The USB device is in resume state
78
#define STATE_RESUME  5
79

    
80
//------------------------------------------------------------------------------
81
//         Internal variables
82
//------------------------------------------------------------------------------
83
/// State of USB, for suspend and resume
84
unsigned char USBState = STATE_IDLE;
85

    
86
/*----------------------------------------------------------------------------
87
 *         VBus monitoring (optional)
88
 *----------------------------------------------------------------------------*/
89

    
90
/**  VBus pin instance. */
91
static const Pin pinVbus = PIN_USB_VBUS;
92

    
93
/* this needs to be in sync with usb-strings.txt !! */
94
enum dfu_altif {
95
	ALTIF_APP,
96
	ALTIF_BOOT,
97
	ALTIF_RAM,
98
	ALTIF_FPGA
99
};
100

    
101
/**
102
 *  Handles interrupts coming from PIO controllers.
103
 */
104
static void ISR_Vbus(const Pin *pPin)
105
{
106
    /* Check current level on VBus */
107
    if (PIO_Get(&pinVbus))
108
    {
109
        //TRACE_INFO("VBUS conn\n\r");
110
        USBD_Connect();
111
    }
112
    else
113
    {
114
        //TRACE_INFO("VBUS discon\n\r");
115
        USBD_Disconnect();
116
    }
117
}
118

    
119
/**
120
 *  Configures the VBus pin to trigger an interrupt when the level on that pin
121
 *  changes.
122
 */
123
static void VBus_Configure( void )
124
{
125
    /* Configure PIO */
126
    PIO_Configure(&pinVbus, 1);
127
    PIO_ConfigureIt(&pinVbus, ISR_Vbus);
128
    PIO_EnableIt(&pinVbus);
129

    
130
    /* Check current level on VBus */
131
    if (PIO_Get(&pinVbus))
132
    {
133
        /* if VBUS present, force the connect */
134
        USBD_Connect();
135
    }
136
    else
137
    {
138
        //TRACE_INFO("discon\n\r");
139
        USBD_Disconnect();
140
    }
141
}
142

    
143
/*----------------------------------------------------------------------------
144
 *         USB Power Control
145
 *----------------------------------------------------------------------------*/
146

    
147
#ifdef PIN_USB_POWER_ENA
148
/** Power Enable A (MicroAB Socket) pin instance. */
149
static const Pin pinPOnA = PIN_USB_POWER_ENA;
150
#endif
151
#ifdef PIN_USB_POWER_ENB
152
/** Power Enable B (A Socket) pin instance. */
153
static const Pin pinPOnB = PIN_USB_POWER_ENB;
154
#endif
155
#ifdef PIN_USB_POWER_ENC
156
/** Power Enable C (A Socket) pin instance. */
157
static const Pin pinPOnC = PIN_USB_POWER_ENC;
158
#endif
159
/**
160
 * Configures the Power Enable pin to disable self power.
161
 */
162
static void USBPower_Configure( void )
163
{
164
  #ifdef PIN_USB_POWER_ENA
165
    PIO_Configure(&pinPOnA, 1);
166
  #endif
167
  #ifdef PIN_USB_POWER_ENB
168
    PIO_Configure(&pinPOnB, 1);
169
  #endif
170
  #ifdef PIN_USB_POWER_ENC
171
    PIO_Configure(&pinPOnC, 1);
172
  #endif
173
}
174

    
175
/*----------------------------------------------------------------------------
176
 *         Callbacks re-implementation
177
 *----------------------------------------------------------------------------*/
178

    
179
//------------------------------------------------------------------------------
180
/// Invoked when the USB device leaves the Suspended state. By default,
181
/// configures the LEDs.
182
//------------------------------------------------------------------------------
183
void USBDCallbacks_Resumed(void)
184
{
185
    // Initialize LEDs
186
    LED_Configure(USBD_LEDPOWER);
187
    LED_Set(USBD_LEDPOWER);
188
    LED_Configure(USBD_LEDUSB);
189
    LED_Clear(USBD_LEDUSB);
190
    USBState = STATE_RESUME;
191
}
192

    
193
//------------------------------------------------------------------------------
194
/// Invoked when the USB device gets suspended. By default, turns off all LEDs.
195
//------------------------------------------------------------------------------
196
void USBDCallbacks_Suspended(void)
197
{
198
    // Turn off LEDs
199
    LED_Clear(USBD_LEDPOWER);
200
    LED_Clear(USBD_LEDUSB);
201
    USBState = STATE_SUSPEND;
202
}
203

    
204
/* USBD callback */
205
void USBDCallbacks_RequestReceived(const USBGenericRequest *request)
206
{
207
	USBDFU_DFU_RequestHandler(request);
208
}
209

    
210
/* USBD callback */
211
void USBDDriverCallbacks_InterfaceSettingChanged(unsigned char interface,
212
						 unsigned char setting)
213
{
214
	//TRACE_INFO("DFU: IfSettingChgd(if=%u, alt=%u)\n\r", interface, setting);
215
}
216

    
217
#define BOOT_FLASH_SIZE		(16 * 1024)
218

    
219
struct flash_part {
220
	void *base_addr;
221
	uint32_t size;
222
};
223

    
224
static const struct flash_part flash_parts[] = {
225
	[ALTIF_BOOT] = {
226
		.base_addr =	AT91C_IFLASH0,
227
		.size =		BOOT_FLASH_SIZE,
228
	},
229
	[ALTIF_APP] = {
230
		.base_addr =	(AT91C_IFLASH + BOOT_FLASH_SIZE),
231
		.size =		(AT91C_IFLASH0_SIZE - BOOT_FLASH_SIZE),
232
	},
233
	[ALTIF_RAM] = {
234
		.base_addr =	AT91C_IRAM,
235
		.size =		AT91C_IRAM_SIZE,
236
	},
237
	[ALTIF_FPGA] = {
238
		.base_addr =	0,
239
		.size =		16*1024*1024, // really no limit
240
	},
241
};
242

    
243
/* DFU callback */
244
int USBDFU_handle_upload(uint8_t altif, unsigned int offset,
245
			 uint8_t *buf, unsigned int req_len)
246
{
247
	return -EINVAL;
248
#if 0
249
	struct flash_part *part;
250
	void *end, *addr;
251
	uint32_t real_len;
252

    
253
	//TRACE_INFO("DFU: handle_upload(%u, %u, %u)\n\r", altif, offset, req_len);
254

    
255
	if (altif > ARRAY_SIZE(flash_parts))
256
		return -EINVAL;
257

    
258
	part = &flash_parts[altif];
259

    
260
	addr = part->base_addr + offset;
261
	end = part->base_addr + part->size;
262

    
263
	real_len = end - addr;
264
	if (req_len < real_len)
265
		real_len = req_len;
266

    
267
	LED_Set(USBD_LEDOTHER);
268
	memcpy(buf, addr, real_len);
269
	LED_Clear(USBD_LEDOTHER);
270

    
271
	return real_len;
272
#endif
273
}
274

    
275
extern unsigned short g_usDataType;
276

    
277
static uint8_t fpgaBuf[1024];
278
static uint fpgaBufStart; // file offset of first byte in buffer
279
static uint fpgaBufEnd;
280
static uint fpgaBufFill;
281
static uint fpgaBufRPtr;
282
static uint fpgaPushedAddr;
283

    
284
short int ispProcessVME();
285
void EnableHardware();
286

    
287
void fpgaPushAddr()
288
{
289
	fpgaPushedAddr = fpgaBufRPtr;
290
}
291

    
292
void fpgaPopAddr()
293
{
294
	printf("*");
295
	fpgaBufRPtr = fpgaPushedAddr;
296
}
297

    
298
uint8_t fpgaGetByte()
299
{
300
	uint8_t res = fpgaBuf[fpgaBufRPtr - fpgaBufStart];
301
	fpgaBufRPtr++;
302

    
303
	return res;
304
}
305

    
306
static int fpgaFlash(unsigned int offset, const uint8_t* buf, unsigned int len)
307
{
308
	int i;
309

    
310
	if(offset == 0) {
311
		for(i = 0; i < len; i++)
312
			fpgaBuf[i] = buf[i];
313
		fpgaBufStart = 0;
314
		fpgaBufEnd = len;
315
		fpgaBufFill = len;
316
		fpgaBufRPtr = 0;
317

    
318
		*((uint32_t*)(0x400e0410)) = (1 << 11);
319
		*((uint32_t*)(0x400e0e00 + 0x44)) = (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8);
320
		*((uint32_t*)(0x400e0e00 + 0x60)) = (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8);
321
		*((uint32_t*)(0x400e0e00 + 0x54)) = (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8);
322
		*((uint32_t*)(0x400e0e00 + 0x10)) = (1 << 5) | (1 << 7) | (1 << 8);
323
		*((uint32_t*)(0x400e0e00 + 0x00)) = (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8);
324

    
325
		if(fpgaGetByte())
326
			g_usDataType = COMPRESS;
327
		else g_usDataType = 0;
328

    
329
	    EnableHardware();
330
	} else {
331
		for(i = 0; i < len; i++)
332
			fpgaBuf[fpgaBufFill + i] = buf[i];
333
		fpgaBufEnd += len;
334
		fpgaBufFill += len;
335
	}
336
/*
337
	printf("\n\rs:%d,e:%d,f:%d,r:%d,p:%d\n",
338
		fpgaBufStart, fpgaBufEnd, fpgaBufFill, fpgaBufRPtr, fpgaPushedAddr);
339
*/
340
	while(fpgaBufEnd - fpgaBufRPtr > 192) {
341
		if((i = ispProcessVME()) < 0)
342
			return -1;
343
	}
344

    
345
	if(fpgaBufFill > 384) {
346
		uint moveby = fpgaBufFill - 384;
347
		uint movelen = fpgaBufFill - movelen;
348

    
349
		for(i = 0; i < movelen; i++)
350
			fpgaBuf[i] = fpgaBuf[i + moveby];
351
		fpgaBufStart += moveby;
352
		fpgaBufFill -= moveby;
353
/*
354
		printf("\n\rs:%d,e:%d,f:%d,r:%d,p:%d\n",
355
			fpgaBufStart, fpgaBufEnd, fpgaBufFill, fpgaBufRPtr, fpgaPushedAddr);
356
*/
357
	}
358

    
359
	return 0;
360
}
361

    
362
/* DFU callback */
363
int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
364
			 uint8_t *buf, unsigned int len)
365
{
366
	struct flash_part *part;
367
	void *end, *addr;
368
	int rc;
369

    
370
	TRACE_INFO("DFU: handle_dnload(%u, %u, %u)\n\r", altif, offset, len);
371

    
372
	if (altif > ARRAY_SIZE(flash_parts))
373
		return -EINVAL;
374

    
375
	part = &flash_parts[altif];
376

    
377
	addr = part->base_addr + offset;
378
	end = part->base_addr + part->size;
379

    
380
	if (addr + len > end) {
381
		TRACE_ERROR("Write beyond end (%u)\n\r", altif);
382
		g_dfu.status = DFU_STATUS_errADDRESS;
383
		return DFU_RET_STALL;
384
	}
385

    
386
	switch (altif) {
387
	case ALTIF_APP:
388
		/* SAM3U Errata 46.2.1.3 */
389
		SetFlashWaitState(6);
390
		LED_Set(USBD_LEDOTHER);
391
		rc = FLASHD_Write(addr, buf, len);
392
		LED_Clear(USBD_LEDOTHER);
393
		/* SAM3U Errata 46.2.1.3 */
394
		SetFlashWaitState(2);
395
		if (rc != 0) {
396
			TRACE_ERROR("Write error (%u)\n\r", altif);
397
			g_dfu.status = DFU_STATUS_errPROG;
398
			return DFU_RET_STALL;
399
		}
400
		break;
401

    
402
	case ALTIF_FPGA:
403
		LED_Set(USBD_LEDOTHER);
404
		rc = fpgaFlash(offset, buf, len);
405
		LED_Clear(USBD_LEDOTHER);
406
		/* SAM3U Errata 46.2.1.3 */
407
		if (rc != 0) {
408
			TRACE_ERROR("FPGA error (ofs %d)\n\r", fpgaBufRPtr);
409
			g_dfu.status = DFU_STATUS_errPROG;
410
			return DFU_RET_STALL;
411
		}
412
		break;
413

    
414
	default:
415
		TRACE_WARNING("Not implemented (%u)\n\r", altif);
416
		g_dfu.status = DFU_STATUS_errTARGET;
417
		break;
418
	}
419

    
420
	return DFU_RET_ZLP;
421
}
422

    
423
/* DFU callback */
424
void dfu_drv_updstatus(void)
425
{
426
	TRACE_INFO("DFU: updstatus()\n\r");
427

    
428
	if (g_dfu.state == DFU_STATE_dfuMANIFEST_SYNC)
429
		g_dfu.state = DFU_STATE_dfuMANIFEST;
430
}
431

    
432
/*----------------------------------------------------------------------------
433
 *         Exported functions
434
 *----------------------------------------------------------------------------*/
435

    
436
extern void USBD_IrqHandler(void);
437
/*
438
static const char *rst_type_strs[8] = {
439
	"General", "Backup", "Watchdog", "Softare", "User", "5", "6", "7"
440
};
441
*/
442
int main(void)
443
{
444
    volatile uint8_t usbConn = 0;
445
    unsigned long rst_type;
446

    
447
    TRACE_CONFIGURE(DBGU_STANDARD, 115200, BOARD_MCK);
448

    
449
    printf("-- Osmocom USB DFU (" BOARD_NAME ") " GIT_REVISION " --\n\r");
450
    printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__);
451

    
452
    rst_type = (RSTC_GetStatus() >> 8) & 0x7;
453
    //printf("-- Reset type: %s --\n\r", rst_type_strs[rst_type]);
454

    
455
    chipid_to_usbserial();
456

    
457
    /* If they are present, configure Vbus & Wake-up pins */
458
    PIO_InitializeInterrupts(0);
459

    
460
    /* Initialize all USB power (off) */
461
    USBPower_Configure();
462

    
463
    /* Audio STREAM LED */
464
    LED_Configure(USBD_LEDOTHER);
465

    
466
    USBDFU_Initialize(&dfu_descriptors);
467

    
468
    /* connect if needed */
469
    VBus_Configure();
470

    
471
    static int state = 0;
472

    
473
    /* Infinite loop */
474
    while (1)
475
    {
476
        if (USBD_GetState() < USBD_STATE_CONFIGURED)
477
        {
478
            usbConn = 0;
479
            continue;
480
        } else
481
		usbConn = 1;
482
	/* This works, but breaks JTAG debugging */
483
	//__WFE();
484
    }
485
}
486
/** \endcond */
(6-6/11)
Add picture from clipboard (Maximum size: 48.8 MB)