int main(void)
{
    /* Enable OCP Master Port */
    PRUCFG_SYSCFG &= ~SYSCFG_STANDBY_INIT;
    cxt.magic = FW_MAGIC;
    while (1) {

        /* Poll for downcalls */
        if(PINTC_SRSR0 & BIT(SYSEV_ARM_TO_PRU0)) {
            PINTC_SICR = SYSEV_ARM_TO_PRU0;
            sc_downcall(handle_downcall);
        }

        /* Run triggered */
        if (state_run == 1) {
            /* Clear all pending interrupts */
            PINTC_SECR0 = 0xFFFFFFFF;

            resume_other_pru();
            run(&cxt, trigger_flags);

            /* Wait for the previous interrupts to be handled */
            while (!(PINTC_SRSR0 & BIT(SYSEV_VR_PRU0_TO_ARM)));
            while ((PINTC_SRSR0 & BIT(SYSEV_VR_PRU0_TO_ARM)));

            /* Signal completion */
            SIGNAL_EVENT(SYSEV_VR_PRU1_TO_ARM);

            /* Reset PRU1 and our state */
            PCTRL_OTHER(0x0000) &= (u16)~CONTROL_SOFT_RST_N;
            state_run = 0;
            trigger_flags = -1;
        }
    }
}
Esempio n. 2
0
static int handle_downcall(u32 id, u32 arg0, u32 arg1, u32 arg2,
		u32 arg3, u32 arg4)
{
	switch (id) {
		case DC_PWM_CONFIG:
			/* return -EINVAL */
			if (arg1 < MIN_PWM_PULSE || arg2 < MIN_PWM_PULSE)
				return -22;
			PWM_CMD->cmd = PWM_CMD_MODIFY;
			PWM_CMD->pwm_nr = arg0;
			PWM_CMD->u.hilo[0] = arg1;
			PWM_CMD->u.hilo[1] = arg2;
			break;
		case DC_PWM_ENABLE:
			PWM_CMD->cmd = PWM_CMD_ENABLE;
			PWM_CMD->pwm_nr = arg0;
			break;
		case DC_PWM_DISABLE:
			PWM_CMD->cmd = PWM_CMD_DISABLE;
			PWM_CMD->pwm_nr = arg0;
			break;
		default:
			sc_printf("bad downcall with id %d", id);
			/* error */
			return -1;
	}

	PWM_CMD->magic = PWM_CMD_MAGIC;
	SIGNAL_EVENT(SYSEV_THIS_PRU_TO_OTHER_PRU);

	return 0;
}
Esempio n. 3
0
static int tx_thread(struct pt *pt)
{
	struct vring_desc *vrd = NULL;
	u32 chunk, i;
	char *ptr, ch;

	PT_BEGIN(pt);

	for (;;) {

		/* wait until we get the indication (and there's a buffer) */
		PT_WAIT_UNTIL(pt, tx_cnt && pru_vring_buf_is_avail(&tx_ring));

		vrd = pru_vring_get_next_avail_desc(&tx_ring);

		/* we don't support VRING_DESC_F_INDIRECT */
		BUG_ON(vrd->flags & VRING_DESC_F_INDIRECT);

		chunk = tx_cnt;
		if (chunk > vrd->len)
			chunk = vrd->len;

		ptr = pa_to_da(vrd->addr);

		for (i = 0; i < chunk; i++) {
			ch = tx_buf[tx_out++ & TX_SIZE_MASK];
			*ptr++ = ch;
		}
		tx_cnt -= chunk;
		vrd->len = chunk;
		vrd->flags &= ~VRING_DESC_F_NEXT;	/* last */

		pru_vring_push_one(&tx_ring, chunk);

		PT_WAIT_UNTIL(pt, !(PINTC_SRSR0 & BIT(SYSEV_VR_THIS_PRU_TO_ARM)));
		SIGNAL_EVENT(SYSEV_VR_THIS_PRU_TO_ARM);
	}

	PT_YIELD(pt);

	PT_END(pt);
}
Esempio n. 4
0
static int handle_downcall(u32 id, u32 arg0, u32 arg1, u32 arg2,
		u32 arg3, u32 arg4)
{
	int max_slots = SHARED_MEM[CONFIG_MAX_SLOTS];

	switch (id) {
		case DC_LED_BLANK:
			blank_slots(arg0);

			break;
		case DC_LED_WRITE:
			write_data(arg0, arg1, arg2);

			break;
		case DC_LED_WRITE_BURST: {
			int i = 0;
			u32 *data = (u32 *) PRU_LED_DATA;

			for (i = 0; i < max_slots; i++) {
				write_data(arg0, i, *data++);
			}
			break;
		}
		case DC_LED_LATCH:
			SIGNAL_EVENT(SYSEV_THIS_PRU_TO_OTHER_PRU);

			break;
		default:
			sc_printf("bad downcall with id %d", id);
			/* error */
			return -EINVAL;
	}

	/* Allow kernel binding to know of slot count  */
	*((u32 *) PRU_LED_DATA) = max_slots;

	return 0;
}
Esempio n. 5
0
static int prompt_thread(struct pt *pt)
{
	static char ch1;
	static char *pp;
	static char linebuf[80];
	char buf[8];
	char *p;
	static int linesz;
	static u8 current_universe;
	u32 val;

	PT_BEGIN(pt);

	for (;;) {
again:
		sprintf((char *) &buf, "PRU#%d> ", current_universe);
		c_puts(buf);
		linesz = sizeof(linebuf);
		c_readline(linebuf, linesz);
		c_puts("\n");
		if (linesz == 0)
			goto again;

		ch1 = linebuf[0];
		pp = "";

		PT_WAIT_UNTIL(pt, !(PINTC_SRSR0 & BIT(SYSEV_THIS_PRU_TO_OTHER_PRU)));

		if (ch1 == '?') {
			c_puts("Help\n"
		 		" s <universe>              "
				"select universe 0-13\n"
		  		" b                         "
				"blanks slots 1-170\n"
				" m <val>                   "
				"max number of slots per universe 0-169\n"
		  		" w <num> <v1>.<v2>.<v3>    "
				"write 24-bit GRB value to slot number\n"
		  		" l                         "
				"latch data out the PRU1\n");
		} else if (ch1 == 's') {
			p = parse_u32(linebuf + 1, &val);
			if (val > MAX_UNIVERSES - 1) {
				pp = "*BAD*\n";
			} else { 
				current_universe = val;
			}
		} else if (ch1 == 'b') {
			blank_slots(current_universe);
		} else if (ch1 == 'm') {
			p = parse_u32(linebuf + 1, &val);
			
			if (val > MAX_SLOTS || val == 0) {
				pp = "*BAD\n";
			} else {
				SHARED_MEM[CONFIG_MAX_SLOTS] = val;
				*((u32 *) PRU_LED_DATA) = val;
			}
		} else if (ch1 == 'w') {
			p = parse_u32(linebuf + 1, &val);

			if (val > MAX_SLOTS) {
				pp = "*BAD*\n";
			} else {
				u32 rgb_data;
				p = parse_u24(p, &rgb_data);
				write_data(current_universe, val, rgb_data);
			}
		} else if (ch1 == 'l') {
			/*
			 * Tell PRU1 to update the LED strings
	 		*/

			SIGNAL_EVENT(SYSEV_THIS_PRU_TO_OTHER_PRU);
		} else {
			pp = "*BAD*\n";
		}

		c_puts(pp);
	}

	PT_YIELD(pt);

	PT_END(pt);
}
Esempio n. 6
0
static int event_thread(struct pt *pt)
{
	static struct pru_vring_elem pvre;
	static u16 idx, count;
	static u32 rx_len, len;
	struct vring_desc *vrd;
	static char *ptr;

	PT_BEGIN(pt);

	for (;;) {
		/* wait until we get the indication */
		PT_WAIT_UNTIL(pt,
			/* pru_signal() && */
			(PINTC_SRSR0 & SYSEV_THIS_PRU_INCOMING_MASK) != 0);

		/* downcall from the host */
		if (PINTC_SRSR0 & BIT(SYSEV_ARM_TO_THIS_PRU)) {
			PINTC_SICR = SYSEV_ARM_TO_THIS_PRU;

			PT_WAIT_UNTIL(pt, !(PINTC_SRSR0 & BIT(SYSEV_THIS_PRU_TO_OTHER_PRU)));
			sc_downcall(handle_downcall);
		}

		if (PINTC_SRSR0 & BIT(SYSEV_VR_ARM_TO_THIS_PRU)) {
			PINTC_SICR = SYSEV_VR_ARM_TO_THIS_PRU;

			while (pru_vring_pop(&rx_ring, &pvre)) {

				/* process the incoming buffers (??? not used) */
				if ((count = pvre.in_num) > 0) {
					idx = pvre.in_idx;
					while (count-- > 0) {
						vrd = pru_vring_desc(&rx_ring, idx);
						ptr = pa_to_da(vrd->addr);
						idx++;
					}
				}

				rx_len = 0;

				/* process the outgoing buffers (this is our RX) */
				if (pvre.out_num > 0) {

					idx = pvre.out_idx;
					count = pvre.out_num;
					while (count-- > 0) {
						vrd = pru_vring_desc(&rx_ring, idx);
						ptr = pa_to_da(vrd->addr);
						len = vrd->len;

						/* put it in the rx buffer (can yield) */
						while (len-- > 0)
							RX_IN(*ptr++);

						rx_len += vrd->len;

						idx++;
					}
				}

				pru_vring_push(&rx_ring, &pvre, rx_len);
				PT_WAIT_UNTIL(pt, !(PINTC_SRSR0 & BIT(SYSEV_VR_THIS_PRU_TO_ARM)));

				/* VRING PRU -> ARM */
				SIGNAL_EVENT(SYSEV_VR_THIS_PRU_TO_ARM);
			}
		}

		if (PINTC_SRSR0 & BIT(SYSEV_OTHER_PRU_TO_THIS_PRU)) {
			PINTC_SICR = SYSEV_OTHER_PRU_TO_THIS_PRU;
		}
	}

	/* get around warning */
	PT_YIELD(pt);

	PT_END(pt);
}
Esempio n. 7
0
File: CC2420.c Progetto: Amagor/app
/*******************************************************************************//**
 * CC2420 thread proc
 **********************************************************************************/
PROC CC2420_ThreadProc(PARAM Param)
{
	uint16_t Val;
	uint8_t i,LQI,Byte;
	int8_t RSSIVal;
	
	// request data
	if(CC2420_OPERATION_IS(PHY_OPERATION_REQUEST_DATA))
	{
		CC2420_STOP_OPERATION(PHY_OPERATION_REQUEST_DATA)
		
		// if transmitter is off signal error
		if(CC2420Defs.State<=CC2420_STATE_IDLE)
		{
			SIGNAL_EVENT(PHYLayer_DATA_Confirm(PHY_TRX_OFF))
			
		}
		// if transmitter is in rx state signal error
		else if(CC2420Defs.State==CC2420_STATE_RX||
		        CC2420Defs.State==CC2420_STATE_RX_GOT_SFD||
		        CC2420Defs.State==CC2420_STATE_RX_REJECT_ALL)
		{
			SIGNAL_EVENT(PHYLayer_DATA_Confirm(PHY_RX_ON))
			
		}
		// everithing is fine, send data
		else
		{
			// if there was tx underflow, then flush tx fifo
			if(CC2420_SendCommandStrobe(CC2420_SNOP)&(1<<CC2420_STATUS_TX_UNDERFLOW))
			{
				// flush tx buffer
				CC2420_SendCommandStrobe(CC2420_SFLUSHTX);
				
			}
			
			// write data to tx fifo
			SPI_Start(CC2420Defs.SPI);
			
			SPI_TxRx(CC2420Defs.SPI,CC2420_TXFIFO,NULL);
			
			#ifdef PHY_LAYER_HANDLE_CHECKSUM
			SPI_TxRx(CC2420Defs.SPI,CC2420Defs.TxLen+2,&Byte);
			#else
			SPI_TxRx(CC2420Defs.SPI,CC2420Defs.TxLen,&Byte);
			#endif
			
			for(i=0;i<CC2420Defs.TxLen;++i)
			{
				SPI_TxRx(CC2420Defs.SPI,CC2420Defs.TxData[i],NULL);
				
			}
			
			SPI_Stop(CC2420Defs.SPI);
			
			// if there was rx fifo overflow, then flush rx fifo twice
			if(CC2420_GetRxFIFOOverflow())
			{
				CC2420_SendCommandStrobe(CC2420_SFLUSHRX);
				CC2420_SendCommandStrobe(CC2420_SFLUSHRX);
				
			}
			
			// begin transmission
			CC2420Defs.State = CC2420_STATE_TX;
			
			CC2420_SendCommandStrobe(CC2420_STXON);
			
		}
		
	}
	
	// request CCA
	if(CC2420_OPERATION_IS(PHY_OPERATION_CCA))
	{
		CC2420_STOP_OPERATION(PHY_OPERATION_CCA)
		
		// if TRX is off, then return this state
		if(CC2420Defs.State<=CC2420_STATE_IDLE)
		{
			SIGNAL_EVENT(PHYLayer_CCA_Confirm(PHY_TRX_OFF))
			
		}
		// if tx is on, then return this state
		else if(CC2420Defs.State==CC2420_STATE_TX||
		        CC2420Defs.State==CC2420_STATE_TX_GOT_SFD)
		{
			SIGNAL_EVENT(PHYLayer_CCA_Confirm(PHY_TX_ON))
			
		}
		// check CCA and return its state
		else if(CC2420_GetCCA())
		{
			SIGNAL_EVENT(PHYLayer_CCA_Confirm(PHY_IDLE))
			
		}
		else
		{
			SIGNAL_EVENT(PHYLayer_CCA_Confirm(PHY_BUSY))
			
		}
		
	}
Esempio n. 8
0
static int prompt_thread(struct pt *pt)
{
	static char ch1;
	static char *pp;
	static char linebuf[80];
	char *p;
	static int linesz;
	u32 val;

	PT_BEGIN(pt);

	PWM_CMD->magic = PWM_REPLY_MAGIC;

	for (;;) {
again:
		c_puts("PRU> ");
		linesz = sizeof(linebuf);
		c_readline(linebuf, linesz);
		c_puts("\n");
		if (linesz == 0)
			goto again;

		ch1 = linebuf[0];

		if (ch1 == '?') {
			c_puts("Help\n"
				" h <us> set high in us\n"
				" l <us> set low in us\n");
		} else if (ch1 == 'e' || ch1 == 'd') {

			/* wait until the command is processed */
			PT_WAIT_UNTIL(pt, PWM_CMD->magic == PWM_REPLY_MAGIC);

			if (ch1 == 'e') 
				PWM_CMD->cmd = PWM_CMD_ENABLE;
			else
				PWM_CMD->cmd = PWM_CMD_DISABLE;

			p = parse_u32(linebuf + 1, &val);
			PWM_CMD->pwm_nr = val;

			PWM_CMD->magic = PWM_CMD_MAGIC;
			SIGNAL_EVENT(SYSEV_THIS_PRU_TO_OTHER_PRU);

		} else if (ch1 == 'm') {

			/* wait until the command is processed */
			PT_WAIT_UNTIL(pt, PWM_CMD->magic == PWM_REPLY_MAGIC);

			PWM_CMD->cmd = PWM_CMD_MODIFY;

			p = parse_u32(linebuf + 1, &val);
			PWM_CMD->pwm_nr = val;

			p = parse_u32(p, &val);
			PWM_CMD->u.hilo[0] = val;

			p = parse_u32(p, &val);
			PWM_CMD->u.hilo[1] = val;

			PWM_CMD->magic = PWM_CMD_MAGIC;
			SIGNAL_EVENT(SYSEV_THIS_PRU_TO_OTHER_PRU);

		} else {
			pp = "*BAD*\n";
		}

		c_puts(pp);
	}

	PT_YIELD(pt);

	PT_END(pt);
}