📄 usb.c
字号:
//#include "config1cfg.h"
#include <c6x.h>
#include <csl_gpio.h>
#include <std.h>
#include <sem.h>
#include <csl_irq.h>
//#include "usb.h"
#include "dsk_appcfg.h"
/* Globale Variablen f黵 die usb Funktionen */
typedef struct
{
GPIO_Handle hGpio;
unsigned int txe, rxf;
unsigned int txeIntCount, rxfIntCount, txBytes, rxBytes;
unsigned int txBPS, rxBPS, rxCount, txCount;
SEM_Obj writeSem;
SEM_Obj readSem;
} tUsb;
tUsb usbStruct;
#define USB_ADDR (0xb0000000)
/*
TXE:
When high, do not write data into the FIFO.\
When low, data can be ritten into the FIFO by strobing WR high then low.
*/
#define USB_PIN_TXE (GPIO_PIN7) // INT7
#define USB_PIN_INT_TXE (GPIO_GPINT7) // INT7
#define USB_INT_TXE (IRQ_EVT_EXTINT7) // INT7
/*
RXF:
When high, do not read data from the FIFO.\
When low, there is data available in the FIFO which can be read by strobing RD# low then high again
*/
#define USB_PIN_RXF (GPIO_PIN6) // INT6
#define USB_PIN_INT_RXF (GPIO_GPINT6) // INT6
#define USB_INT_RXF (IRQ_EVT_EXTINT6) // INT6
/* Initalisiert die Hardware
Vor allen anderen Funktionen aufrufen!!!
*/
int usbInit()
{
IRQ_globalDisable(); // alle Interrups ausschalten
usbStruct.rxf = 0;
usbStruct.txe = 0;
usbStruct.rxBytes = 0;
usbStruct.txBytes = 0;
usbStruct.txBPS = 0;
usbStruct.txCount = 0;
usbStruct.rxBPS = 0;
usbStruct.rxCount = 0;
//_EMIF_CECTL3_ADDR 0x01800014u
*(unsigned volatile int *) 0x01800014u = 0xFFFFFF07; // set CE3 8bit async, slow
// FIFO Status leitungen Initalisieren
usbStruct.hGpio = GPIO_open(GPIO_DEV0,GPIO_OPEN_RESET);
GPIO_pinEnable(usbStruct.hGpio, (USB_PIN_RXF));
GPIO_pinEnable(usbStruct.hGpio, (USB_PIN_TXE));
GPIO_pinDirection(usbStruct.hGpio, (USB_PIN_RXF), GPIO_INPUT);
GPIO_pinDirection(usbStruct.hGpio, (USB_PIN_TXE), GPIO_INPUT);
usbStruct.rxfIntCount = 0;
SEM_new(&usbStruct.readSem, 0); // semaphore intialisieren
GPIO_intPolarity(usbStruct.hGpio,USB_PIN_INT_RXF, GPIO_FALLING);
IRQ_reset(USB_INT_RXF);
usbStruct.txeIntCount = 0;
SEM_new(&usbStruct.writeSem, 0); // semaphore intialisieren
GPIO_intPolarity(usbStruct.hGpio,USB_PIN_INT_TXE, GPIO_FALLING);
IRQ_reset(USB_INT_TXE);
IRQ_globalEnable();
return 1;
}
/*
Interrupt Handler f黵 den TXE Interrup.
Im DSP Bios nicht vergessen den Dipatcher zu aktivieren
*/
void usbIntTxe(void)
{
usbStruct.txeIntCount++; // f黵 statistik
usbStruct.txe = 0;
IRQ_reset(USB_INT_TXE); // Interrupt wieder ausschalten
SEM_post(&usbStruct.writeSem); // Schreibprozess aufwecken
}
/*
Interrupt Handler f黵 den RXF Interrup.
Im DSP Bios nicht vergessen den Dipatcher zu aktivieren
*/
void usbIntRxf(void)
{
usbStruct.rxfIntCount++; // f黵 statistik
usbStruct.rxf = 0;
IRQ_reset(USB_INT_RXF); // Interrupt wieder ausschalten
SEM_post(&usbStruct.readSem); // Leseprozess aufwecken
}
/* Gibt zur點k ob ein Byte in den Empfangs FIFO gelesen werden kann */
int usbReadCharReady(void)
{
return GPIO_pinRead (usbStruct.hGpio, USB_PIN_RXF) == 0;
}
/* Gibt zur點k ob ein Byte in den Sende FIFO geschriben werden kann */
int usbWriteCharReady(void)
{
return GPIO_pinRead (usbStruct.hGpio, USB_PIN_TXE) == 0;
}
/*
ALLE NACHFOLGENDEN FUKTIONEN M躍SEN AUS EINEM DSP BIOS PROZESS AUFGERUFEN WERDEN !!!!!
*/
/*
Liest ein Byte aus dem Emfangs FIFO des FTDI245BM Chips.
Ist das fifo leer wird der Prozess blockiert und auf Daten gewartet
*/
char usbReadChar(void)
{
char data;
// Interruptflag k鰊nte durch zwischenzeitliche Pegel鋘derungen gesetzt sein
IRQ_reset(USB_INT_RXF);
// Status des RXF Pins abfragen
usbStruct.rxf = GPIO_pinRead (usbStruct.hGpio, USB_PIN_RXF);
// wenn rxf = 0, dann sind daten im FIFO und wir k鰊nen lesen.
if(usbStruct.rxf != 0)
{
// wenn rxf = 1, dann sind noch keine Daten im FIFO und
// wir m黶sen warten bis die RXF leitung auf 1 geht.
IRQ_enable(USB_INT_RXF); // Interrupt einschalten, steigende Flanke
// Prozess blockieren, wird vom Interrupt wieder aktiviert
SEM_pend(&usbStruct.readSem, SYS_FOREVER);
}
data = *(unsigned volatile char *)USB_ADDR; // daten aus dem FIFO lesen
usbStruct.rxBytes++; // fuer Statistik
usbStruct.rxCount++; // fuer Statistik
return data;
}
/*
Schreibt ein Byte in den Sende FIFO.
Ist der FIFO voll wird der Prozess blockiert und gewartet bis
platz im FIFO ist.
*/
char usbWriteChar(char data)
{
IRQ_reset(USB_INT_TXE);
usbStruct.txe = GPIO_pinRead (usbStruct.hGpio, USB_PIN_TXE);
if(usbStruct.txe != 0)
{
IRQ_enable(USB_INT_TXE);
SEM_pend(&usbStruct.writeSem, SYS_FOREVER);
}
*(unsigned volatile char *)USB_ADDR = data; // daten in das Sende FIFO schreiben
usbStruct.txBytes++; // fuer Statistik
usbStruct.txCount++; // fuer Statistik
return data;
}
/*
Sendet einen null terminierten String an den PC
*/
int usbWriteString(char *s)
{
for(;*s;s++)
{
usbWriteChar(*s);
}
return 1;
}
/*
sendet nBytes Anzahl von Bytes an den PC
Beispiel:
TSK_main() // muss ein DSP/BIOS Prozess sein
{
char buf[11]= "Hallo World";
usbWriteBuffer(&buf, size(buf));
}
*/
int usbWriteBuffer(char *buf, unsigned int nBytes)
{
if(!buf) return 0; // pr黤t ob ein g黮tiger Pointer 黚ergeben wurde.
for(;nBytes;nBytes--)
{
usbWriteChar(*buf);
buf++;
}
return nBytes;
}
/*
empf鋘gt nBytes Anzahl Bytes vom PC.
Wartet so lange bis die entsprechende anzahl an Bytes empfangen wurde
*/
int usbReadBuffer(char *buf, unsigned int nBytes)
{
if(!buf) return 0; // pr黤t ob ein g黮tiger Pointer 黚ergeben wurde.
for(;nBytes;nBytes--)
{
*buf = usbReadChar();
buf++;
}
return nBytes;
}
/* Diese Funktion sollte alle 10 Sekunden ausgef黨rt werden, wenn man die aktuelle Transferrate wissen m鯿hte,
muss aber auch nicht*/
void PRD_usb_main()
{
usbStruct.txBPS = usbStruct.txCount/10;
usbStruct.txCount = 0;
usbStruct.rxBPS = usbStruct.rxCount/10;
usbStruct.rxCount = 0;
LOG_printf(&LOG0,"USB rxBPS=%d txBPS=%d",usbStruct.rxBPS,usbStruct.txBPS); // Ausgabe zum CCS (IDE)
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -