No, I don't use ticker but I use adc interrupt.
my code is:
#include "mbed.h"
#include "USBHID.h"
#include "stdio.h"
#include "tanimlamalar.h"
void adcInit(uint32_t ADC_Clk );
extern "C" void ADC_IRQHandler (void) __irq ;
uint32_t ADCRead( uint8_t );
void sinyalVer(void);
volatile uint32_t OverRunCounter = 0;
volatile uint32_t ADCIntDone = 0, tumPiksellerOkundu = 0;
void changeRowCol(unsigned char row, unsigned char column);
void changeRowColOwnCode(unsigned char row, unsigned char column);
unsigned int rowBusData[64] = {0,512,64,576,2,514,66,578,256,768,320,832,258,770,322,834,1,513,65,577,3,515,67,579,257,769,321,833,259,771,323,835,128,640,192,704,130,642,194,706,384,896,448,960,386,898,450,962,129,641,193,705,131,643,195,707,385,897,449,961,387,899,451,963};
//We declare a USBHID device. By default input and output reports are 64 bytes long.
//USBHID hid(64,8 ,0x1234,0x0006);
USBHID hid(64, 64);
//This report will contain data to be sent
HID_REPORT send_report;
HID_REPORT recv_report;
//AnalogIn adcCInput(p16); //Cartesian array i�in analog giri�
PwmOut pwm(p21);
DigitalOut adcToggle(p20); //adc okurken toggle yap�p kontrol ediyorum sadece
DigitalOut transmitLed(LED1);
DigitalOut receiveLed(LED2);
DigitalOut debugLed(LED3);
DigitalOut donguLed(LED4);
BusInOut cRowBus(p5, p8, p10, p6, p9, p7); //Cartesian array sat�r pinleri. s�ras� �nemli
BusInOut cColBus(p25, p26, p29, p27, p28, p30); //Cartesian array s�tun pinleri
volatile unsigned char mainStateMachine =0, colIndex=0,rowIndex=0,sayac=0,colIndexTemp=0,rowIndexTemp=0 ;
volatile unsigned int pixels[64][64],adcValue,averageCount,tempInteger,tempInteger1;
volatile unsigned long averageValue;
float pwmDutyCycleValue=0.50;
unsigned int pwmPeriodUs=654;
char c=0;
int main() {
send_report.length = 64;
cColBus.mode(OpenDrain);
cColBus.output();
cRowBus.mode(OpenDrain);
cRowBus.output();
pwm.period_us(pwmPeriodUs);
pwm = pwmDutyCycleValue;
if (averageCount==0) averageCount=1;
mainStateMachine=bekle;
adcInit(13000000);
ADCRead(1);
while (1) {
if (OverRunCounter>0) {
while (1) {
donguLed=~donguLed;
wait_ms(500);
}
}
//try to read a msg
if (hid.readNB(&recv_report)) {
receiveLed = !receiveLed;
switch (recv_report.data[komut]) {
case sadeceBirPikselOku:
rowIndexTemp=recv_report.data[2]; // istenen piksel numaras�n� sakl�yorum.
colIndexTemp=recv_report.data[3];
//changeRowCol(rowIndex,colIndex); //uygun kanala gec
averageCount=recv_report.data[4]*256; //Average de�erini al
averageCount+=recv_report.data[5];
send_report.data[0]=sadeceBirPikselOku; //Komut
send_report.data[1]=rowIndexTemp; //Parametre 1
send_report.data[2]=colIndexTemp; //Parametre 2
send_report.data[3]=(char)((pixels[rowIndexTemp][colIndexTemp])>>8&0x00FF);
send_report.data[4]=(char)((pixels[rowIndexTemp][colIndexTemp])&0x00FF);
send_report.data[5]=(char)((int)(pwmDutyCycleValue*1000)>>8&0x00ff);
send_report.data[6]=(char)((int)(pwmDutyCycleValue*1000)&0x00ff);
send_report.data[7]=(char)((averageCount>>8)&0x00ff);
send_report.data[8]=(char)(averageCount&0x00ff);
hid.send(&send_report);
transmitLed=!transmitLed;
break;
case averageSayisiYaz:
averageCount=recv_report.data[2]*256;
averageCount+=recv_report.data[3];
break;
case tumunuToptanGonder:
for (rowIndexTemp=0; rowIndexTemp<64; rowIndexTemp++) {
for (colIndexTemp=0; colIndexTemp<32; colIndexTemp++) {
send_report.data[(colIndexTemp*2)]=(char)(pixels[rowIndexTemp][colIndexTemp] >> 8) & 0x00FF;
send_report.data[(colIndexTemp*2)+1]=(char)(pixels[rowIndexTemp][colIndexTemp] & 0x00FF);
}
hid.send(&send_report);
for (colIndexTemp=32; colIndexTemp<64; colIndexTemp++) {
send_report.data[(colIndexTemp-32)*2]=(char)(pixels[rowIndexTemp][colIndexTemp] >> 8) & 0x00FF;
send_report.data[(colIndexTemp-32)*2+1]=(char)(pixels[rowIndexTemp][colIndexTemp] & 0x00FF);
}
hid.send(&send_report);
}
break;
case pwmPeriyodYaz:
tempInteger=recv_report.data[2]*256; // pwmFrekans i�in gelen us cinsinden periyot s�resi
tempInteger+=recv_report.data[3];
if (tempInteger>0) {
pwm.period_us(tempInteger);
}
tempInteger=recv_report.data[4]*256; // pwmDutyCycle degeri
tempInteger+=recv_report.data[5];
pwm = (float)tempInteger/1000;
pwmDutyCycleValue=pwm.read();
break;
} // switch recv_report.data
} //if (hid.readNB(&recv_report))
} //while(1)
} //main
void changeRowCol(unsigned char row, unsigned char column) {
cRowBus.write(row);
cColBus.write(column);
}
void adcInit(uint32_t ADC_Clk) {
uint32_t pclkdiv, pclk;
/* Enable CLOCK into ADC controller */
LPC_SC->PCONP |= (1 << 12);
/* all the related pins are set to ADC inputs, AD0.0~7 */
LPC_PINCON->PINSEL1 &= ~0x00030000; //p0.24 fonksiyonunu s�f�rlar
LPC_PINCON->PINSEL1 |= 0x00010000; //p0.24'�n� ad0.1 fonksiyonuna atar
/* No pull-up no pull-down (function 10) on these ADC pins. */
LPC_PINCON->PINMODE1 &= ~0x00030000; //p0.24 pinmode s�f�rlar
LPC_PINCON->PINMODE1 |= 0x00020000; //p0.24 pull-up or pull-down yok
/* By default, the PCLKSELx value is zero, thus, the PCLK for
all the peripherals is 1/4 of the SystemCoreClock. */
/* Bit 24~25 is for ADC */
pclkdiv = (LPC_SC->PCLKSEL0 >> 24) & 0x03;
switch ( pclkdiv ) {
case 0x00:
default:
pclk = SystemCoreClock/4;
break;
case 0x01:
pclk = SystemCoreClock;
break;
case 0x02:
pclk = SystemCoreClock/2;
break;
case 0x03:
pclk = SystemCoreClock/8;
break;
}
LPC_ADC->ADCR = ( 0x01 << 1 ) | /* SEL=1,select channel 0~7 on ADC0 */
( ( pclk / ADC_Clk - 1 ) << 8 ) | /* CLKDIV = Fpclk / ADC_Clk - 1 */
( 0 << 16 ) | /* BURST = 0, no BURST, software controlled */
( 0 << 17 ) | /* CLKS = 0, 11 clocks/10 bits */
( 1 << 21 ) | /* PDN = 1, normal operation */
( 0 << 24 ) | /* START = 0 A/D conversion stops */
( 0 << 27 ); /* EDGE = 0 (CAP/MAT singal falling,trigger A/D conversion) */
/* If POLLING, no need to do the following */
NVIC_EnableIRQ(ADC_IRQn);
//LPC_ADC->ADINTEN = 0x1FF; /* Enable all interrupts */
LPC_ADC->ADINTEN = 0x102;
return;
}
extern "C" void ADC_IRQHandler (void) __irq {
uint32_t regVal;
volatile uint32_t dummy;
regVal = LPC_ADC->ADSTAT; /* Read ADC will clear the interrupt */
if ( regVal & 0x0000FF00 ) { /* check OVERRUN error first */
OverRunCounter++;
regVal = (regVal & 0x0000FF00) >> 0x08;
/* if overrun, just read ADDR to clear */
/* regVal variable has been reused. */
dummy = LPC_ADC->ADDR0;
dummy = LPC_ADC->ADDR1;
dummy = LPC_ADC->ADDR2;
LPC_ADC->ADCR &= ~((0x7<<24)|(0x1<<16)); /* stop ADC now, turn off BURST bit. */
ADCIntDone = 1;
return;
}
adcValue = ( LPC_ADC->ADDR1 >> 4 ) & 0xFFF;
pixels[rowIndex][colIndex]=adcValue;
if (colIndex<63) {
colIndex++;
} else {
colIndex=0;
rowIndex++;
if (rowIndex==64) {
rowIndex=0;
}
}
changeRowCol(rowIndex,colIndex);
// LPC_ADC->ADCR &= ~(0x7<<24); /* stop ADC now */
LPC_ADC->ADCR |= (1 << 24) ; //ADC durmadan devam ediyor.
ADCIntDone = 1;
return;
}
/*****************************************************************************
** Function name: ADCRead
**
** Descriptions: Read ADC channel
**
** parameters: Channel number
** Returned value: Value read, if interrupt driven, return channel #
**
*****************************************************************************/
uint32_t ADCRead( uint8_t channelNum ) {
//LPC_ADC->ADCR &= 0xFFFFFF00;
LPC_ADC->ADCR |= (1 << 24) ;//| (1 << channelNum);
/* switch channel,start A/D convert */
return ( channelNum ); /* if it's interrupt driven, the ADC reading is
done inside the handler. so, return channel number */
}
void sinyalVer(void) {
debugLed=1;
wait_ms(100);
debugLed=0;
wait_ms(100);
debugLed=1;
wait_ms(100);
debugLed=0;
}
Hello,
I need to send to the Mbed 528bytes 25 times per second.
So I used HID USB on mbed and HIDAPI on my computer (with Qt). I make messages from 63bytes (and I add a "0x00" Report ID) to send a complete transfert to the mbed.
It works great but the data rate transfert is really bad (8kB/s to send the 528bytes...) I don't see how I can improve this rate. Can you help me?
Thanks a lot!