mirror of
				https://github.com/eried/portapack-mayhem.git
				synced 2025-11-03 20:24:06 -05:00 
			
		
		
		
	* enabled usb clock * added usb stack to application * fixed pll0usb clock setup * implemented serial usb handshake * implemented serial communication * integrated chibios shell * implemented device reset * implemented enter dfu mode * implemented hackrf mode command * implemented flash command * implemented memory manipulation * implemented button control * fixed mode change * improved reset behavior * implemented directory commands * implemented file commands * improved data communication * refactorings
		
			
				
	
	
		
			142 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			142 lines
		
	
	
	
		
			4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (C) 2023 Bernd Herzog
 | 
						|
 *
 | 
						|
 * This file is part of PortaPack.
 | 
						|
 *
 | 
						|
 * This program is free software; you can redistribute it and/or modify
 | 
						|
 * it under the terms of the GNU General Public License as published by
 | 
						|
 * the Free Software Foundation; either version 2, or (at your option)
 | 
						|
 * any later version.
 | 
						|
 *
 | 
						|
 * This program is distributed in the hope that it will be useful,
 | 
						|
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
 * GNU General Public License for more details.
 | 
						|
 *
 | 
						|
 * You should have received a copy of the GNU General Public License
 | 
						|
 * along with this program; see the file COPYING.  If not, write to
 | 
						|
 * the Free Software Foundation, Inc., 51 Franklin Street,
 | 
						|
 * Boston, MA 02110-1301, USA.
 | 
						|
 */
 | 
						|
 | 
						|
#include "usb_serial_io.h"
 | 
						|
 | 
						|
#include "usb_serial_endpoints.h"
 | 
						|
 | 
						|
#pragma GCC diagnostic push
 | 
						|
// external code, so ignore warnings
 | 
						|
#pragma GCC diagnostic ignored "-Wstrict-prototypes"
 | 
						|
 | 
						|
#include <common/usb.h>
 | 
						|
#include <common/usb_request.h>
 | 
						|
#include <common/usb_standard_request.h>
 | 
						|
#include <hackrf_usb/usb_device.h>
 | 
						|
#include <hackrf_usb/usb_endpoint.h>
 | 
						|
 | 
						|
#pragma GCC diagnostic pop
 | 
						|
 | 
						|
#include <usb_request.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
SerialUSBDriver SUSBD1;
 | 
						|
 | 
						|
void bulk_out_receive(void) {
 | 
						|
    int ret;
 | 
						|
    do {
 | 
						|
        ret = usb_transfer_schedule(
 | 
						|
            &usb_endpoint_bulk_out,
 | 
						|
            &usb_endpoint_bulk_out.buffer[0],
 | 
						|
            32,
 | 
						|
            serial_bulk_transfer_complete,
 | 
						|
            NULL);
 | 
						|
 | 
						|
    } while (ret != -1);
 | 
						|
}
 | 
						|
 | 
						|
void serial_bulk_transfer_complete(void* user_data, unsigned int bytes_transferred) {
 | 
						|
    (void)user_data;
 | 
						|
 | 
						|
    chSysLockFromIsr();
 | 
						|
 | 
						|
    for (unsigned int i = 0; i < bytes_transferred; i++) {
 | 
						|
        msg_t ret;
 | 
						|
        do {
 | 
						|
            ret = chIQPutI(&SUSBD1.iqueue, usb_endpoint_bulk_out.buffer[i]);
 | 
						|
            if (ret == Q_FULL)
 | 
						|
                chThdSleepMilliseconds(1);
 | 
						|
 | 
						|
        } while (ret == Q_FULL);
 | 
						|
    }
 | 
						|
 | 
						|
    chSysUnlockFromIsr();
 | 
						|
}
 | 
						|
 | 
						|
static void onotify(GenericQueue* qp) {
 | 
						|
    SerialUSBDriver* sdp = chQGetLink(qp);
 | 
						|
    int n = chOQGetFullI(&sdp->oqueue);
 | 
						|
    if (n > 0) {
 | 
						|
        for (int i = 0; i < n; i++) {
 | 
						|
            usb_endpoint_bulk_in.buffer[i] = chOQGetI(&sdp->oqueue);
 | 
						|
        }
 | 
						|
 | 
						|
        int ret;
 | 
						|
        chSysUnlock();
 | 
						|
        do {
 | 
						|
            ret = usb_transfer_schedule(
 | 
						|
                &usb_endpoint_bulk_in,
 | 
						|
                &usb_endpoint_bulk_in.buffer[0],
 | 
						|
                n,
 | 
						|
                NULL,
 | 
						|
                NULL);
 | 
						|
 | 
						|
            if (ret == -1)
 | 
						|
                chThdSleepMilliseconds(1);
 | 
						|
 | 
						|
        } while (ret == -1);
 | 
						|
        chSysLock();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
static size_t write(void* ip, const uint8_t* bp, size_t n) {
 | 
						|
    return chOQWriteTimeout(&((SerialUSBDriver*)ip)->oqueue, bp,
 | 
						|
                            n, TIME_INFINITE);
 | 
						|
}
 | 
						|
 | 
						|
static size_t read(void* ip, uint8_t* bp, size_t n) {
 | 
						|
    return chIQReadTimeout(&((SerialUSBDriver*)ip)->iqueue, bp,
 | 
						|
                           n, TIME_INFINITE);
 | 
						|
}
 | 
						|
 | 
						|
static msg_t put(void* ip, uint8_t b) {
 | 
						|
    return chOQPutTimeout(&((SerialUSBDriver*)ip)->oqueue, b, TIME_INFINITE);
 | 
						|
}
 | 
						|
 | 
						|
static msg_t get(void* ip) {
 | 
						|
    return chIQGetTimeout(&((SerialUSBDriver*)ip)->iqueue, TIME_INFINITE);
 | 
						|
}
 | 
						|
 | 
						|
static msg_t putt(void* ip, uint8_t b, systime_t timeout) {
 | 
						|
    return chOQPutTimeout(&((SerialUSBDriver*)ip)->oqueue, b, timeout);
 | 
						|
}
 | 
						|
 | 
						|
static msg_t gett(void* ip, systime_t timeout) {
 | 
						|
    return chIQGetTimeout(&((SerialUSBDriver*)ip)->iqueue, timeout);
 | 
						|
}
 | 
						|
 | 
						|
static size_t writet(void* ip, const uint8_t* bp, size_t n, systime_t time) {
 | 
						|
    return chOQWriteTimeout(&((SerialUSBDriver*)ip)->oqueue, bp, n, time);
 | 
						|
}
 | 
						|
 | 
						|
static size_t readt(void* ip, uint8_t* bp, size_t n, systime_t time) {
 | 
						|
    return chIQReadTimeout(&((SerialUSBDriver*)ip)->iqueue, bp, n, time);
 | 
						|
}
 | 
						|
 | 
						|
static const struct SerialUSBDriverVMT vmt = {
 | 
						|
    write, read, put, get,
 | 
						|
    putt, gett, writet, readt};
 | 
						|
 | 
						|
void init_serial_usb_driver(SerialUSBDriver* sdp) {
 | 
						|
    sdp->vmt = &vmt;
 | 
						|
    chIQInit(&sdp->iqueue, sdp->ib, SERIAL_BUFFERS_SIZE, NULL, sdp);
 | 
						|
    chOQInit(&sdp->oqueue, sdp->ob, SERIAL_BUFFERS_SIZE, onotify, sdp);
 | 
						|
}
 |