My baud rate should be 115200, but it is 892.9
void UART0_Init(int pclk, int baudrate)
{
unsigned long int DLest;
//unsigned long int pclk;
unsigned int temp;
// Turn on power to UART0
SC->PCONP |= PCUART0_POWERON;
// Set PINSEL0 so that P0.2 = TXD0, P0.3 = RXD0
PINCON->PINSEL0 = (PINCON->PINSEL0 & ~0xf0) | (1 << 4) | (1 << 6);
UART0->LCR = 0x83; // 8 bits, no Parity, 1 Stop bit, DLAB=1
DLest = (pclk / 16) / baudrate; // Set baud rate
UART0->DLM = DLest / 256;
UART0->DLL = DLest % 256;
// UART0->FDR =
UART0->IER = 0x7; //enable RBR (b0), THRE(b1), RLS(b2)
UART0->LCR = 0x03; // 8 bits, no Parity, 1 Stop bit DLAB = 0
UART0->FCR = 0x07; // Enable and reset TX and RX FIFO
}
void prvSetupHardware( void )
{
/* Disable peripherals power. */
SC->PCONP = 0;
/* Enable GPIO power. */
SC->PCONP = PCONP_PCGPIO;
/* Disable TPIU. */
PINCON->PINSEL10 = 0;
if ( SC->PLL0STAT & ( 1 << 25 ) )
{
/* Enable PLL, disconnected. */
SC->PLL0CON = 1;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
}
/* Disable PLL, disconnected. */
SC->PLL0CON = 0;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
/* Enable main OSC. */
SC->SCS |= 0x20;
while( !( SC->SCS & 0x40 ) );
/* select main OSC, 12MHz, as the PLL clock source. */
SC->CLKSRCSEL = 0x1;
SC->PCLKSEL0 = 0xAAAAAAAA; /* PCLK is 1/2 CCLK */
SC->PCLKSEL1 = 0xAAAAAAAA;
/*Fcc0 = 400MHz, M = 50, N = 3*/
SC->PLL0CFG = 0x20031;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
/* Enable PLL, disconnected. */
SC->PLL0CON = 1;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
/* Set clock divider. */
/*Clock = 100MHz, Fcc0 = 400MHz*/
SC->CCLKCFG = 0x03;//divided by 4.
/* Configure flash accelerator. */
SC->FLASHCFG = 0x403a;
/* Check lock bit status. */
while( ( ( SC->PLL0STAT & ( 1 << 26 ) ) == 0 ) );
/* Enable and connect. */
SC->PLL0CON = 3;
SC->PLL0FEED = PLLFEED_FEED1;
SC->PLL0FEED = PLLFEED_FEED2;
while( ( ( SC->PLL0STAT & ( 1 << 25 ) ) == 0 ) );
/* Configure the clock for the USB. */
if( SC->PLL1STAT & ( 1 << 9 ) )
{
/* Enable PLL, disconnected. */
SC->PLL1CON = 1;
SC->PLL1FEED = PLLFEED_FEED1;
SC->PLL1FEED = PLLFEED_FEED2;
}
/* Disable PLL, disconnected. */
SC->PLL1CON = 0;
SC->PLL1FEED = PLLFEED_FEED1;
SC->PLL1FEED = PLLFEED_FEED2;
SC->PLL1CFG = 0x23;
SC->PLL1FEED = PLLFEED_FEED1;
SC->PLL1FEED = PLLFEED_FEED2;
/* Enable PLL, disconnected. */
SC->PLL1CON = 1;
SC->PLL1FEED = PLLFEED_FEED1;
SC->PLL1FEED = PLLFEED_FEED2;
while( ( ( SC->PLL1STAT & ( 1 << 10 ) ) == 0 ) );
/* Enable and connect. */
SC->PLL1CON = 3;
SC->PLL1FEED = PLLFEED_FEED1;
SC->PLL1FEED = PLLFEED_FEED2;
while( ( ( SC->PLL1STAT & ( 1 << 9 ) ) == 0 ) );
/* Configure the LEDs. */
vParTestInitialise();
/*pclk = 100MHZ/2, baud = 115200 */
UART0_Init(100000000/2, 115200);
/* Set the sleep mode to highest level sleep*/
SC->PCON = 0x0;
SCB->SCR = 0x0;
/*set push button interrupt */
PINCON->PINSEL4 |= 0x00100000;
SC->EXTMODE =0;
NVIC_SetPriority( EINT0_IRQn, configUIButton1_INTERRUPT_PRIORITY );
NVIC_EnableIRQ( EINT0_IRQn );
NVIC_SetPriority( UART0_IRQn, configUIButton1_INTERRUPT_PRIORITY + 1 );
NVIC_EnableIRQ( UART0_IRQn );
}
I have confirmed that my cclk is running at 100MHz.
I replace the UART init code with code from an example project by Kunil (uart_interrupt_demo):
void uart_init(int baudrate) {
int errorStatus = -1; //< Failure
long int SystemFrequency = 100000000;
// UART clock (FCCO / PCLK_UART0)
unsigned int uClk = SystemFrequency / 4;
unsigned int calcBaudrate = 0;
unsigned int temp = 0;
unsigned int mulFracDiv, dividerAddFracDiv;
unsigned int divider = 0;
unsigned int mulFracDivOptimal = 1;
unsigned int dividerAddOptimal = 0;
unsigned int dividerOptimal = 0;
unsigned int relativeError = 0;
unsigned int relativeOptimalError = 100000;
// Turn on power to UART0
SC->PCONP |= PCUART0_POWERON;
// Change P0.2 and P0.3 mode to TXD0 and RXD0
PINCON->PINSEL0 = (1 << 4) | (1 << 6);
// Set 8N1 mode
UART0->LCR = 0x83;
// Set the baud rate
uClk = uClk >> 4; /* div by 16 */
/*
* The formula is :
* BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * DLL)
*/
/*
* The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions:
* 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15
*/
for (mulFracDiv = 1; mulFracDiv <= 15; mulFracDiv++) {
for (dividerAddFracDiv = 0; dividerAddFracDiv <= 15; dividerAddFracDiv++) {
temp = (mulFracDiv * uClk) / (mulFracDiv + dividerAddFracDiv);
divider = temp / baudrate;
if ((temp % baudrate) > (baudrate / 2))
divider++;
if (divider > 2 && divider < 65536) {
calcBaudrate = temp / divider;
if (calcBaudrate <= baudrate) {
relativeError = baudrate - calcBaudrate;
} else {
relativeError = calcBaudrate - baudrate;
}
if (relativeError < relativeOptimalError) {
mulFracDivOptimal = mulFracDiv;
dividerAddOptimal = dividerAddFracDiv;
dividerOptimal = divider;
relativeOptimalError = relativeError;
if (relativeError == 0)
break;
}
}
}
if (relativeError == 0)
break;
}
if (relativeOptimalError
< ((baudrate * UART_ACCEPTED_BAUDRATE_ERROR) / 100)) {
UART0->LCR |= DLAB_ENABLE;
UART0->DLM = (unsigned char) ((dividerOptimal >> 8) & 0xFF);
UART0->DLL = (unsigned char) dividerOptimal;
UART0->LCR &= ~DLAB_ENABLE;
UART0->FDR = ((mulFracDivOptimal << 4) & 0xF0) | (dividerAddOptimal
& 0x0F);
errorStatus = 0; //< Success
}
// Enable TX and RX FIFO
UART0->FCR |= FIFO_ENABLE;
// Set FIFO to trigger when at least 14 characters available
UART0->FCR |= (3 << 6);
// Enable UART RX interrupt (for LPC17xx UART)
UART0->IER = RBR_IRQ_ENABLE;
// Enable the UART interrupt (for Cortex-CM3 NVIC)
NVIC_EnableIRQ(UART0_IRQn);
}
And it works!
I have to go through and see what i had wrong. I suspect the order of register settings was off.
Have a look at the Errata sheet.
You can't set SC->PCLKSEL0 after you fired up the main PLL, so the divider stays at CCLK/4.
Just move the line
/* Setup the peripheral bus to be the same as the PLL output (64 MHz). */
SC->PCLKSEL0 = 0x05555555;
a few lines up, before you enable the PLL.
Suspect that clk for UART is further divided from the cclk. You need to check the datasheet and update accordingly.
I wanted a simplified driver for my LPC1768 UART1 port so I have written a baud rate calculator application based on CMSIS code.
You provide the Peripheral Clock Frequency and Desired Baud Rate and it will generate the DLL, Fractional Multiplier & Divider and finally recalculates with the computed values to indicate the Baud rate achievable.
I have tested it with a peripheral clock of 25MHz and baud rates of 115200 & 9600 with success. It does not calculate DLM which is generally 0 for bauds above 4800.
It is available at a freeware download site.
http://sabercathost.com/6y6
I have a reputation to maintain and to that end the application I uploaded does not contain a virus.
HTH
Mark
As requested by Drew I've appended the CMSIS function I used in my code below.
/*********************************************************************//**
* #brief Determines best dividers to get a target clock rate
* #param[in] UARTx Pointer to selected UART peripheral, should be:
* - LPC_UART0: UART0 peripheral
* - LPC_UART1: UART1 peripheral
* - LPC_UART2: UART2 peripheral
* - LPC_UART3: UART3 peripheral
* #param[in] baudrate Desired UART baud rate.
* #return Error status, could be:
* - SUCCESS
* - ERROR
**********************************************************************/
static Status uart_set_divisors(LPC_UART_TypeDef *UARTx, uint32_t baudrate)
{
Status errorStatus = ERROR;
uint32_t uClk;
uint32_t d, m, bestd, bestm, tmp;
uint64_t best_divisor, divisor;
uint32_t current_error, best_error;
uint32_t recalcbaud;
/* get UART block clock */
if (UARTx == LPC_UART0)
{
uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART0);
}
else if (UARTx == (LPC_UART_TypeDef *)LPC_UART1)
{
uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART1);
}
else if (UARTx == LPC_UART2)
{
uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART2);
}
else if (UARTx == LPC_UART3)
{
uClk = CLKPWR_GetPCLK (CLKPWR_PCLKSEL_UART3);
}
/* In the Uart IP block, baud rate is calculated using FDR and DLL-DLM registers
* The formula is :
* BaudRate= uClk * (mulFracDiv/(mulFracDiv+dividerAddFracDiv) / (16 * (DLL)
* It involves floating point calculations. That's the reason the formulae are adjusted with
* Multiply and divide method.*/
/* The value of mulFracDiv and dividerAddFracDiv should comply to the following expressions:
* 0 < mulFracDiv <= 15, 0 <= dividerAddFracDiv <= 15 */
best_error = 0xFFFFFFFF; /* Worst case */
bestd = 0;
bestm = 0;
best_divisor = 0;
for (m = 1 ; m <= 15 ;m++)
{
for (d = 0 ; d < m ; d++)
{
divisor = ((uint64_t)uClk<<28)*m/(baudrate*(m+d));
current_error = divisor & 0xFFFFFFFF;
tmp = divisor>>32;
/* Adjust error */
if(current_error > ((uint32_t)1<<31)){
current_error = -current_error;
tmp++;
}
if(tmp<1 || tmp>65536) /* Out of range */
continue;
if( current_error < best_error){
best_error = current_error;
best_divisor = tmp;
bestd = d;
bestm = m;
if(best_error == 0) break;
}
} /* end of inner for loop */
if (best_error == 0)
break;
} /* end of outer for loop */
if(best_divisor == 0) return ERROR; /* can not find best match */
recalcbaud = (uClk>>4) * bestm/(best_divisor * (bestm + bestd));
/* reuse best_error to evaluate baud error*/
if(baudrate>recalcbaud) best_error = baudrate - recalcbaud;
else best_error = recalcbaud -baudrate;
best_error = best_error * 100 / baudrate;
if (best_error < UART_ACCEPTED_BAUDRATE_ERROR)
{
if (((LPC_UART1_TypeDef *)UARTx) == LPC_UART1)
{
((LPC_UART1_TypeDef *)UARTx)->LCR |= UART_LCR_DLAB_EN;
((LPC_UART1_TypeDef *)UARTx)->/*DLIER.*/DLM = UART_LOAD_DLM(best_divisor);
((LPC_UART1_TypeDef *)UARTx)->/*RBTHDLR.*/DLL = UART_LOAD_DLL(best_divisor);
/* Then reset DLAB bit */
((LPC_UART1_TypeDef *)UARTx)->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;
((LPC_UART1_TypeDef *)UARTx)->FDR = (UART_FDR_MULVAL(bestm) \
| UART_FDR_DIVADDVAL(bestd)) & UART_FDR_BITMASK;
}
else
{
UARTx->LCR |= UART_LCR_DLAB_EN;
UARTx->/*DLIER.*/DLM = UART_LOAD_DLM(best_divisor);
UARTx->/*RBTHDLR.*/DLL = UART_LOAD_DLL(best_divisor);
/* Then reset DLAB bit */
UARTx->LCR &= (~UART_LCR_DLAB_EN) & UART_LCR_BITMASK;
UARTx->FDR = (UART_FDR_MULVAL(bestm) \
| UART_FDR_DIVADDVAL(bestd)) & UART_FDR_BITMASK;
}
errorStatus = SUCCESS;
}
return errorStatus;
}
Related
In MPLAB X IDE v5.10, I am using dspic33ep512mu810 microcontroller.
I have following piece of C code:
#include "xc.h"
_FOSCSEL(FNOSC_FRCPLL) //INT OSC with PLL (always keep this setting)
_FOSC(OSCIOFNC_OFF & POSCMD_NONE) //disable external OSC
_FWDT(FWDTEN_OFF) //watchdog timer off
_FICD(JTAGEN_OFF & 0b11); //JTAG debugging off
void UART2TX(char c) {
if (U2STAbits.UTXEN == 0)
U2STAbits.UTXEN = 1; //enable UART TX
while (U2STAbits.UTXBF == 1); //if buffer is full, wait
U2TXREG = c;
}
int main(void) {
//setup internal clock for 80MHz/40MIPS
//7.37/2=3.685*43=158.455/2=79.2275
CLKDIVbits.PLLPRE = 0; // PLLPRE (N2) 0=/2
PLLFBD = 41; //pll multiplier (M) = +2
CLKDIVbits.PLLPOST = 0; // PLLPOST (N1) 0=/2
while (!OSCCONbits.LOCK); //wait for PLL ready
_U2TXIF = 0;
_U2TXIE = 0;
_U2RXIF = 0;
_U2RXIE = 0;
//setup UART
U2BRG = 85; //86#80mhz, 85#79.xxx=115200
U2MODE = 0; //clear mode register
U2MODEbits.BRGH = 1; //use high percison baud generator
U2STA = 0; //clear status register
//DSPIC33EP512MU810T-I/PT, RP96 as TX pin
RPOR7bits.RP96R = 3; //
while (1) {
UART2TX('H');
}
}
I am trying to send out 'H' through UART2 with baud rate 115200, but it is not working.
You had to switch RF0 (RP96) aus output:
TRISFbits.TRISF0 = 0; //make F0 an onput
And you had to switch RFO to digital:
ANSELFbits.ANSF0 = 0; //make F0 digital
I've solved an lp using CPLEX callable library (in VS2010). The lp is the following:
Maximize
obj: x1 + 2 x2 + 3 x3
Subject To
c1: - x1 + x2 + x3 <= 20
c2: x1 - 3 x2 + x3 <= 30
Bounds
0 <= x1 <= 40
End
The code is given beneath. Now I would like to make it an MIP (additional integrality constraints on the x's). I tried to do so by changing status = CPXlpopt (env, lp); into status = CPXmipopt (env, lp);. This does not work and I get the error 3003: not a mixed-integer problem. Does anybody know what I am missing here?
int main ()
{
/* Declare and allocate space for the variables and arrays where we
will store the optimization results including the status, objective
value, variable values, dual values, row slacks and variable
reduced costs. */
int solstat;
double objval;
double *x = NULL;
double *pi = NULL;
double *slack = NULL;
double *dj = NULL;
CPXENVptr env = NULL;
CPXLPptr lp = NULL;
int status = 0;
int i, j;
int cur_numrows, cur_numcols;
/* Initialize the CPLEX environment */
env = CPXopenCPLEX (&status);
/* Turn on output to the screen */
status = CPXsetintparam (env, CPX_PARAM_SCRIND, CPX_ON);
/* Turn on data checking */
status = CPXsetintparam (env, CPX_PARAM_DATACHECK, CPX_ON);
/* Create the problem. */
lp = CPXcreateprob (env, &status, "lpex1");
/* Now populate the problem with the data. */
#define NUMROWS 2
#define NUMCOLS 3
#define NUMNZ 6
/* To populate by column, we first create the rows, and then add the columns. */
int status = 0;
double obj[NUMCOLS];
double lb[NUMCOLS];
double ub[NUMCOLS];
char *colname[NUMCOLS];
int matbeg[NUMCOLS];
int matind[NUMNZ];
double matval[NUMNZ];
double rhs[NUMROWS];
char sense[NUMROWS];
char *rowname[NUMROWS];
CPXchgobjsen (env, lp, CPX_MAX); /* Problem is maximization */
/* Now create the new rows. First, populate the arrays. */
rowname[0] = "c1";
sense[0] = 'L';
rhs[0] = 20.0;
rowname[1] = "c2";
sense[1] = 'L';
rhs[1] = 30.0;
status = CPXnewrows (env, lp, NUMROWS, rhs, sense, NULL, rowname);
if ( status ) goto TERMINATE;
/* Now add the new columns. First, populate the arrays. */
obj[0] = 1.0; obj[1] = 2.0; obj[2] = 3.0;
matbeg[0] = 0; matbeg[1] = 2; matbeg[2] = 4;
matind[0] = 0; matind[2] = 0; matind[4] = 0;
matval[0] = -1.0; matval[2] = 1.0; matval[4] = 1.0;
matind[1] = 1; matind[3] = 1; matind[5] = 1;
matval[1] = 1.0; matval[3] = -3.0; matval[5] = 1.0;
lb[0] = 0.0; lb[1] = 0.0; lb[2] = 0.0;
ub[0] = 40.0; ub[1] = CPX_INFBOUND; ub[2] = CPX_INFBOUND;
colname[0] = "x1"; colname[1] = "x2"; colname[2] = "x3";
status = CPXaddcols (env, lp, NUMCOLS, NUMNZ, obj, matbeg, matind, matval, lb, ub, colname);
/* Optimize the problem and obtain solution. */
status = CPXlpopt (env, lp);
cur_numrows = CPXgetnumrows (env, lp);
cur_numcols = CPXgetnumcols (env, lp);
x = (double *) malloc (cur_numcols * sizeof(double));
slack = (double *) malloc (cur_numrows * sizeof(double));
dj = (double *) malloc (cur_numcols * sizeof(double));
pi = (double *) malloc (cur_numrows * sizeof(double));
status = CPXsolution (env, lp, &solstat, &objval, x, pi, slack, dj);
/* Write the output to the screen. */
printf ("\nSolution status = %d\n", solstat);
printf ("Solution value = %f\n\n", objval);
for (i = 0; i < cur_numrows; i++) {
printf ("Row %d: Slack = %10f Pi = %10f\n", i, slack[i], pi[i]);
}
for (j = 0; j < cur_numcols; j++) {
printf ("Column %d: Value = %10f Reduced cost = %10f\n",
j, x[j], dj[j]);
}
/* Finally, write a copy of the problem to a file. */
status = CPXwriteprob (env, lp, "lpex1.lp", NULL);
/* Free up the solution */
... (additional code to free up the solution)...
return(status)
}
In your code, you are not declaring any decision variables to be integer. That's why cplex is complaining when you try to solve your problem using a MIP solver. You are doing column-wise modeling and CPXaddcols doesn't have have a parameter for the variable type, but you can use CPXcopyctype or CPXchgctype. Since you the bounds on your decision variables are all greater than 1, you are looking for the 'I' variable type, instead of 'B' for binary.
char *ctype;
ctype = (char *) malloc(cur_numcols * sizeof(char);
for (j = 0; j < cur_numcols; j++) {
ctype[j] = 'I';
}
status = CPXcopyctype(env, lp, ctype);
/* verify status */
status = CPXmipopt (env, lp);
/* verify status */
I am using X264 and librtmp to send my live camera frame, all the things seems right. but my web test flash can't show the correct video. Sometimes it seems correct, but when I re-click play button, it doesn't show any picture on the flash.
Here is my X264 config code
x264_param_default_preset(&x264param, "ultrafast", "zerolatency");
x264param.i_threads = 2;
x264param.i_width = width;
x264param.i_height = height;
x264param.i_log_level = X264_LOG_DEBUG;
x264param.i_fps_num = x264param.i_timebase_num= fps;
x264param.i_fps_den = x264param.i_timebase_den=1;
x264param.i_frame_total = 0;
x264param.i_frame_reference =1;
//x264param.i_frame_reference = 2;
x264param.i_keyint_min = 25;
x264param.i_keyint_max = fps*3;
x264param.i_scenecut_threshold = 40;
x264param.b_deblocking_filter = 1;
x264param.b_cabac = 0;
x264param.analyse.i_trellis = 0;
x264param.analyse.b_chroma_me = 1;
x264param.vui.i_sar_width = 0;
x264param.vui.i_sar_height = 0;
x264param.i_bframe_bias = 0;
x264param.b_interlaced= 0;
x264param.analyse.i_subpel_refine = 6; /* 0..5 -> 1..6 */
x264param.analyse.i_me_method = X264_ME_DIA;//X264_ME_HEX?X264_ME_DIA
x264param.analyse.i_me_range = 16;
x264param.analyse.i_direct_mv_pred = X264_DIRECT_PRED_AUTO;
x264param.i_deblocking_filter_alphac0 = 0;
x264param.i_deblocking_filter_beta = 0;
//x264param.analyse.intra = X264_ANALYSE_I4x4;
x264param.analyse.intra = X264_ANALYSE_I4x4;// | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16;
x264param.analyse.inter = X264_ANALYSE_I4x4 | X264_ANALYSE_PSUB16x16 | X264_ANALYSE_BSUB16x16;
//edit 2014-7-28
x264param.analyse.b_transform_8x8 = 1;
//x264param.analyse.b_transform_8x8 = 0;
x264param.analyse.b_fast_pskip = 1;
x264param.i_bframe = 0;
//x264param.b_intra_refresh
x264param.analyse.b_weighted_bipred = 0;
//// Intra refres:
x264param.i_keyint_max = 250;
x264param.b_intra_refresh = 0;
////Rate control:
//x264param.rc.i_rc_method = X264_RC_CRF;
//Rate Control
x264param.rc.f_ip_factor = 1.4f;
x264param.rc.f_pb_factor = 1.3f;
x264param.rc.f_qcompress = 1.0;
x264param.rc.i_qp_min = 20;//20;
x264param.rc.i_qp_max = 32;
x264param.rc.i_qp_step = 1;
switch (0)
{
case 0: /* 1 PASS ABR */
x264param.rc.i_rc_method = X264_RC_ABR;
x264param.rc.i_bitrate = 300; // max = 5000
x264param.rc.b_mb_tree = 0;
break;
case 1: /* 1 PASS CQ */
x264param.rc.i_rc_method = X264_RC_CQP;
x264param.rc.i_qp_constant = 26;//10 - 51
break;
}
//For streaming:
x264param.b_repeat_headers = 1;
x264param.b_annexb = 1;
x264_param_apply_profile(&x264param, "baseline");
encoder = x264_encoder_open(&x264param);
x264_picture_init( &pic_in );
x264_picture_alloc(&pic_in, X264_CSP_I420, width, height);
pic_in.img.i_csp = X264_CSP_I420|X264_CSP_VFLIP;
pic_in.img.i_plane = 3;
pic_in.i_type = X264_TYPE_AUTO;
Sending To RTMP:
sws_scale(convertCtx,&a,&scribe,0,height, pic_in.img.plane, pic_in.img.i_stride);
int i_nal;
int i_frame_size = x264_encoder_encode( encoder, &nal, &i_nal, &pic_in, &pic_out );
if(i_frame_size <= 0){
printf("\t!!!FAILED encode frame \n");
}else{
for (int i = 0,last=0; i < i_nal;i++)
{
fwrite(nal[i].p_payload, 1, i_frame_size-last, fpw1);
if (nal[i].i_type == NAL_SPS) {
sps_len = nal[i].i_payload-4;
sps = new unsigned char[sps_len];
memcpy(sps,nal[i].p_payload+4,sps_len);
} else if (nal[i].i_type == NAL_PPS) {
pps_len = nal[i].i_payload-4;
pps = new unsigned char[sps_len];
memcpy(pps,nal[i].p_payload+4,pps_len);
send_video_sps_pps();
free(sps);
free(pps);
} else {
send_rtmp_video(nal[i].p_payload,i_frame_size-last);
break;
}
last += nal[i].i_payload;
}
}
Send PPS and SPS
void send_video_sps_pps(){
if(rtmp!= NULL){
RTMPPacket * packet;
unsigned char * body;
int i;
packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE+1024);
memset(packet,0,RTMP_HEAD_SIZE);
packet->m_body = (char *)packet + RTMP_HEAD_SIZE;
body = (unsigned char *)packet->m_body;
i = 0;
body[i++] = 0x17;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
body[i++] = 0x00;
/*AVCDecoderConfigurationRecord*/
body[i++] = 0x01;
body[i++] = sps[1];
body[i++] = sps[2];
body[i++] = sps[3];
body[i++] = 0xff;
/*sps*/
body[i++] = 0xe1;
body[i++] = (sps_len >> 8) & 0xff;
body[i++] = sps_len & 0xff;
memcpy(&body[i],sps,sps_len);
i += sps_len;
/*pps*/
body[i++] = 0x01;
body[i++] = (pps_len >> 8) & 0xff;
body[i++] = (pps_len) & 0xff;
memcpy(&body[i],pps,pps_len);
i += pps_len;
packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;
packet->m_nBodySize = i;
packet->m_nChannel = 0x04;
packet->m_nTimeStamp = 0;
packet->m_hasAbsTimestamp = 0;
packet->m_headerType = RTMP_PACKET_SIZE_MEDIUM;
packet->m_nInfoField2 = rtmp->m_stream_id;
RTMP_SendPacket(rtmp,packet,TRUE);
free(packet);
rtmp_start_time = GetTickCount();
}else{
std::cout<<"RTMP is not ready"<<std::endl;
}
}
Send video Frame
void send_rtmp_video(unsigned char * buf,int len){
RTMPPacket * packet;
long timeoffset = GetTickCount() - rtmp_start_time;
int type = buf[0]&0x1f;
packet = (RTMPPacket *)malloc(RTMP_HEAD_SIZE+len+9);
memset(packet,0,RTMP_HEAD_SIZE);
packet->m_body = (char *)packet + RTMP_HEAD_SIZE;
packet->m_nBodySize = len + 9;
/*send video packet*/
unsigned char *body = (unsigned char *)packet->m_body;
memset(body,0,len+9);
/*key frame*/
body[0] = 0x27;
if (type == NAL_SLICE_IDR) {
body[0] = 0x17;
}
body[1] = 0x01; /*nal unit*/
body[2] = 0x00;
body[3] = 0x00;
body[4] = 0x00;
body[5] = (len >> 24) & 0xff;
body[6] = (len >> 16) & 0xff;
body[7] = (len >> 8) & 0xff;
body[8] = (len ) & 0xff;
/*copy data*/
memcpy(&body[9],buf,len);
packet->m_hasAbsTimestamp = 0;
packet->m_packetType = RTMP_PACKET_TYPE_VIDEO;
if(rtmp != NULL){
packet->m_nInfoField2 = rtmp->m_stream_id;
}
packet->m_nChannel = 0x04;
packet->m_headerType = RTMP_PACKET_SIZE_LARGE;
packet->m_nTimeStamp = timeoffset;
if(rtmp != NULL){
RTMP_SendPacket(rtmp,packet,TRUE);
}
free(packet);
}
Try changing:
pps = new unsigned char[sps_len];
to:
pps = new unsigned char[pps_len];
I have code that works "ok" for reading the USCI (UART) via interrupts, but the TI SimpliciTI stack is a CPU hog and it drops UART bytes when servicing the radio.
I assume DMA is the way to go, but I couldn't find a full example of DMA using USCI as input.
Here's what I ended up doing. It works!
struct {
#ifndef USE_DMA
volatile uint8_t rx_head ;
#endif
volatile uint8_t rx_tail ;
uint8_t rx_buffer[128];
} uart = { 0,0};
void UART_Init(void)
{
#ifndef USE_DMA
uart.rx_head = 0;
#endif
uart.rx_tail = 0;
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
PMAPPWD = 0x02D52; // Get write-access to port mapping regs
P1MAP5 = PM_UCA0RXD; // Map UCA0RXD output to P1.5
P1MAP6 = PM_UCA0TXD; // Map UCA0TXD output to P1.6
PMAPPWD = 0; // Lock port mapping registers
P1DIR |= BIT6; // Set P1.6 as TX output
P1SEL |= BIT5 + BIT6; // Select P1.5 & P1.6 to UART function
UCA0CTL1 = UCSWRST; // **Put state machine in reset**
#ifdef UART_9600
UCA0CTL1 |= UCSSEL_1; // CLK = ACLK
UCA0BR0 = 0x03; // 32kHz/9600=3.41 (see User's Guide)
UCA0BR1 = 0x00; //
UCA0MCTL = UCBRS_3+UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
#elif defined(UART_9600_SMCLK)
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 0xE2; // 12MHz/12500
UCA0BR1 = 0x04; //
UCA0MCTL = UCBRS_2+UCBRF_0; // Modulation UCBRSx=3, UCBRFx=0
#elif defined(UART_115200)
UCA0CTL1 |= UCSSEL_2; // SMCLK
UCA0BR0 = 104; // 12MHz/115200
UCA0BR1 = 0; //
UCA0MCTL = UCBRS_1 + UCBRF_0; // Modulation UCBRSx=1, UCBRFx=0
#else
#error Please select one of the supported baudrates.
#endif
UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine**
#ifdef USE_DMA
memset(uart.rx_buffer,0,sizeof(uart.rx_buffer));
DMACTL0 = DMA0TSEL_16; // USCIA0 RX trigger
DMA0SAL = (uint16_t) &UCA0RXBUF; // Source address
DMA0DAL = (uint16_t) uart.rx_buffer; // Destination address
DMA0SZ = sizeof(uart.rx_buffer); // Block size. this counts down to 0, then reloads.
DMA0CTL = DMADSTINCR_3 + DMASBDB + DMADT_4 + DMALEVEL;
DMA0CTL |= DMAEN;
#else
UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt
#endif
}
int UART_GetChar(void)
{
#ifdef USE_DMA
if (DMA0SZ + uart.rx_tail != sizeof(uart.rx_buffer))
#else
if ( uart.rx_head != uart.rx_tail )
#endif
{
int c;
c = uart.rx_buffer[uart.rx_tail];
uint8_t next = uart.rx_tail + 1;
if (next >= sizeof(uart.rx_buffer)) next = 0;
uart.rx_tail = next;
return c;
}
return -1;
}
I am trying to build a very simple USB communication device using pic 18f4550
with default mikroelectronica example with no change (only change with hardware that I don't have couple of 100nf attached with vusb so I replaced them with 470uf
and I didn't put any pf with my crystal oscillator)
The hardware:
The code is working very will with Proteus simulation:
unsigned char k;
unsigned char userWR_buffer[64];
const char *text = "MIKROElektronika Compilers ER \r\n";
//**************************************************************************************************
// Main Interrupt Routine
//**************************************************************************************************
void interrupt()
{
HID_InterruptProc();
}
//**************************************************************************************************
//**************************************************************************************************
// Initialization Routine
//**************************************************************************************************
void Init_Main()
{
//--------------------------------------
// Disable all interrupts
//--------------------------------------
INTCON = 0; // Disable GIE, PEIE, TMR0IE,INT0IE,RBIE
INTCON2 = 0xF5;
INTCON3 = 0xC0;
RCON.IPEN = 0; // Disable Priority Levels on interrupts
PIE1 = 0;
PIE2 = 0;
PIR1 = 0;
PIR2 = 0;
ADCON1 |= 0x0F; // Configure all ports with analog function as digital
CMCON |= 7; // Disable comparators
//--------------------------------------
// Ports Configuration
//--------------------------------------
TRISA = 0xFF;
TRISB = 0xFF;
TRISC = 0xFF;
TRISD = 0;
TRISE = 0x07;
LATA = 0;
LATB = 0;
LATC = 0;
LATD = 0;
LATE = 0;
//--------------------------------------
// Clear user RAM
// Banks [00 .. 07] ( 8 x 256 = 2048 Bytes )
//--------------------------------------
}
//**************************************************************************************************
//**************************************************************************************************
// Main Program Routine
//**************************************************************************************************
void main() {
char i;
Init_Main();
HID_Enable(&userWR_buffer, &userWR_buffer);
Delay_ms(1000);
Delay_ms(1000);
while(1) {
Delay_ms(1000);
i=0;
while(text[i]) {
userWR_buffer[0]= text[i++];
while (!HID_Write(&userWR_buffer, 1));
}
}
Delay_ms(1000);
HID_Disable();
}
//**************************************************************************************************
I didn't put any pf with my crystal oscillator
I don't think this will work. Check with an oscilloscope what happens on your crystal. Your device has simply no clock input so it never executes anything.