Exemplo n.º 1
0
/* 
 * This is a dummy function, used as demonstration
 */
SFPResult dummyFunction(SFPFunction *msg) {
	/* Check for arg count */
	if (SFPFunction_getArgumentCount(msg) != 1) return SFP_ERR_ARG_COUNT;
	/* Check for arg type */
	if (SFPFunction_getArgumentType(msg, 0) != SFP_ARG_INT) return SFP_ERR_ARG_TYPE;
	/* Get the argument */
	uint32_t dummyData = SFPFunction_getArgument_int32(msg, 0);

	/* Do some stupid things */
	LPC_GPIO->DIR[1] = 1 << 14;
	if (dummyData)
	    LPC_GPIO->SET[1] = 1 << 14;
	else
	    LPC_GPIO->CLR[1] = 1 << 14;

	/* Start a new frame */
	SFPFunction *outFunc = SFPFunction_new();
	if (outFunc == NULL) return SFP_ERR_ALLOC_FAILED;
	/* Then fill the frame */
	SFPFunction_setType(outFunc, SFPFunction_getType(msg));
	SFPFunction_setID(outFunc, 200); /* Put the Function ID */
	SFPFunction_setName(outFunc, "dummy"); /* Put the function name */
	SFPFunction_addArgument_int32(outFunc, dummyData); /* Put the values you want to send back */  
	/* Send it */
	SFPFunction_send(outFunc, &stream);
	/* End finalize */
	SFPFunction_delete(outFunc);

	return SFP_OK;
}
Exemplo n.º 2
0
SFPResult lpc_pwm0_begin(SFPFunction *msg) {
	if (SFPFunction_getArgumentCount(msg) != 1)
		return SFP_ERR_ARG_COUNT;

	if (SFPFunction_getArgumentType(msg, 0) != SFP_ARG_INT) return SFP_ERR_ARG_TYPE;

	uint32_t p_cyclePeriod = (SFPFunction_getArgument_int32(msg, 0)-1) & 0xFFFF;	// 16 bit value in microseconds

	LPC_SYSCON->SYSAHBCLKCTRL |= BIT7;	// enable clock for CT16B0

	// MAT3 is configured as the driving clock for PWM
	LPC_CT16B0->TCR = BIT0 | BIT1;	// Enable timer, but keep in reset state
	LPC_CT16B0->PR = 48-1;	// 48MHz/48 = 1MHz (1us)

	LPC_CT16B0->MCR = BIT10; // Reset timer on MR3
	LPC_CT16B0->MR3 = p_cyclePeriod; // Set PWM cycle period
	LPC_CT16B0->MR2 = p_cyclePeriod+1; // Set 0% duty cycle (100% off time)
	LPC_CT16B0->MR1 = p_cyclePeriod+1; // Set 0% duty cycle
	LPC_CT16B0->MR0 = p_cyclePeriod+1; // Set 0% duty cycle

	LPC_CT16B0->EMR = 0x02A0; // External outputs enabled: channels 0-2 set high on match
	LPC_CT16B0->PWMC = 0x7;   // PWM channels enabled: set channels 0-2 to PWM control

	LPC_CT16B0->TCR &= ~BIT1;	// disable reset

	return SFP_OK;
}
Exemplo n.º 3
0
Arquivo: main.c Projeto: drasko/UPER-1
SFPResult lpc_system_restart(SFPFunction *msg) {
	if (SFPFunction_getArgumentCount(msg) != 0) return SFP_ERR_ARG_COUNT;

	Time_delay(1000); // Delay 1s before restarting
	NVIC_SystemReset();

	return SFP_OK; // This code should not be reached
}
Exemplo n.º 4
0
SFPResult lpc_pwm0_end(SFPFunction *msg) {
	if (SFPFunction_getArgumentCount(msg) != 0)
		return SFP_ERR_ARG_COUNT;

	LPC_CT16B0->EMR = 0; 	// Disable external outputs
	LPC_CT16B0->PWMC = 0;   // Disable PWM channels

	LPC_CT16B0->TCR = 0;	// Disable timer
	LPC_SYSCON->SYSAHBCLKCTRL &= ~BIT7;	// Disable clock for CT16B0

	return SFP_OK;
}
Exemplo n.º 5
0
SFPResult lpc_1wire_trans(SFPFunction *msg) {
	if (SFPFunction_getArgumentCount(msg) != 1)
		return SFP_ERR_ARG_COUNT;

	if (SFPFunction_getArgumentType(msg, 0) != SFP_ARG_BYTE_ARRAY)
		return SFP_ERR_ARG_TYPE;

	uint8_t port = 0;
	uint8_t pinNum = LPC_PIN_IDS[pin];
	if (pinNum > 23) {	// if not PIO0_0 to PIO0_23
		port = 1;
		pinNum -= 24;
	}

	uint32_t len = 0;
	uint8_t *buf = SFPFunction_getArgument_barray(msg, 0, &len);

	int delay_high, delay_low;

	__disable_irq();
	while (len--) {
		uint8_t b = *buf++;
		int n;

#define BIT0H  4
#define BIT0L  19
#define BIT1H  16
#define BIT1L  4-2

		for (n=7; n>=0; n--) { // MSB first
			if (b & (1 << n)) {
				delay_high = BIT1H;
				delay_low = BIT1L;
			} else {
				delay_high = BIT0H;
				delay_low = BIT0L;
			}

			LPC_GPIO->SET[port] = (1 << pinNum);
			while (delay_high--) __asm("nop");
			LPC_GPIO->CLR[port] = (1 << pinNum);
			while (delay_low--) __asm("nop");
		}

	}
	__enable_irq();

	return SFP_OK;
}
Exemplo n.º 6
0
SFPResult lpc_detachInterrupt(SFPFunction *msg) {
    if (SFPFunction_getArgumentCount(msg) != 1)
        return SFP_ERR_ARG_COUNT;

    if (SFPFunction_getArgumentType(msg, 0) != SFP_ARG_INT) return SFP_ERR_ARG_TYPE;

    uint8_t p_intID = SFPFunction_getArgument_int32(msg, 0);	// interrupt ID

    NVIC_DisableIRQ(p_intID);	// Disable interrupt. XXX: Luckily FLEX_INTx_IRQn == x, so it can be used this way, otherwise BE AWARE!
    LPC_GPIO_PIN_INT->CIENR = (1 << p_intID);	// Disable rising edge or level interrupt
    LPC_GPIO_PIN_INT->CIENF = (1 << p_intID);	// Disable falling edge interrupt
    LPC_GPIO_PIN_INT->RISE = (1 << p_intID);	// Clear rising edge (sort of) flag
    LPC_GPIO_PIN_INT->FALL = (1 << p_intID);	// Clear falling edge (sort of) flag

    return SFP_OK;
}
Exemplo n.º 7
0
Arquivo: main.c Projeto: drasko/UPER-1
SFPResult lpc_system_getDeviceInfo(SFPFunction *msg) {
	if (SFPFunction_getArgumentCount(msg) != 0) return SFP_ERR_ARG_COUNT;

	SFPFunction *func = SFPFunction_new();

	if (func == NULL) return SFP_ERR_ALLOC_FAILED;

	SFPFunction_setType(func, SFPFunction_getType(msg));
	SFPFunction_setID(func, UPER_FID_GETDEVICEINFO);
	SFPFunction_setName(func, UPER_FNAME_GETDEVICEINFO);
	SFPFunction_addArgument_int32(func, UPER_FIRMWARE_VERSION);
	SFPFunction_addArgument_barray(func, (uint8_t*)&GUID[0], 16);
	SFPFunction_addArgument_int32(func, UPER_PART_NUMBER);
	SFPFunction_addArgument_int32(func, UPER_BOOT_CODE_VERSION);
	SFPFunction_send(func, &stream);
	SFPFunction_delete(func);

	return SFP_OK;
}
Exemplo n.º 8
0
SFPResult lpc_pwm0_set(SFPFunction *msg) {
	if (SFPFunction_getArgumentCount(msg) != 2)
			return SFP_ERR_ARG_COUNT;

	if (SFPFunction_getArgumentType(msg, 0) != SFP_ARG_INT
			|| SFPFunction_getArgumentType(msg, 1) != SFP_ARG_INT)
		return SFP_ERR_ARG_TYPE;

	uint32_t p_channelID = SFPFunction_getArgument_int32(msg, 0);			// PWM channel ID [0-2]
	uint32_t p_highTime = SFPFunction_getArgument_int32(msg, 1);	// PWM signal high time in microseconds

	if (p_channelID > 2) return SFP_ERR_ARG_VALUE;

	while (LPC_CT16B0->TC != 0);

	if (LPC_CT16B0->MR3 < p_highTime)
		LPC_CT16B0->MR[p_channelID] = 0;	// Set full high time (0 low time)
	else
		LPC_CT16B0->MR[p_channelID] = LPC_CT16B0->MR3 + 1 - p_highTime;	// Set PWM low time

	return SFP_OK;
}
Exemplo n.º 9
0
SFPResult lpc_1wire_begin(SFPFunction *msg) {
	if (SFPFunction_getArgumentCount(msg) != 1)
			return SFP_ERR_ARG_COUNT;

	if (SFPFunction_getArgumentType(msg, 0) != SFP_ARG_INT)
			return SFP_ERR_ARG_TYPE;

	pin = SFPFunction_getArgument_int32(msg, 0);

	uint8_t port = 0;
	uint8_t pinNum = LPC_PIN_IDS[pin];
	if (pinNum > 23) {	// if not PIO0_0 to PIO0_23
		port = 1;
		pinNum -= 24;
	}

	*LPC_PIN_REGISTERS[pin] &= ~LPC_PIN_MODE_MASK;	// Remove pull-up/down resistors
	LPC_GPIO->DIR[port] |= (1 << pinNum);	// Set direction bit (output)
	LPC_GPIO->CLR[port] = (1 << pinNum);

	return SFP_OK;
}
Exemplo n.º 10
0
SFPResult lpc_attachInterrupt(SFPFunction *func) {
    if (SFPFunction_getArgumentCount(func) != 4)
        return SFP_ERR_ARG_COUNT;

    if (SFPFunction_getArgumentType(func, 0) != SFP_ARG_INT
            || SFPFunction_getArgumentType(func, 1) != SFP_ARG_INT
            || SFPFunction_getArgumentType(func, 2) != SFP_ARG_INT
            || SFPFunction_getArgumentType(func, 3) != SFP_ARG_INT)
        return SFP_ERR_ARG_TYPE;

    uint8_t p_intID = SFPFunction_getArgument_int32(func, 0);	// interrupt ID
    uint8_t p_pin = SFPFunction_getArgument_int32(func, 1);	// pin ID
    uint8_t p_mode = SFPFunction_getArgument_int32(func, 2);	// interrupt mode
    uint32_t p_downtime = SFPFunction_getArgument_int32(func, 3); // down time

    if (p_pin >= LPC_PIN_COUNT || p_intID >= LPC_INTERRUPT_COUNT || p_mode > 4) return SFP_ERR_ARG_VALUE;

    NVIC_DisableIRQ(p_intID);	// Disable interrupt. XXX: Luckily FLEX_INTx_IRQn == x, so it can be used this way, otherwise BE AWARE!

    LPC_SYSCON->PINTSEL[p_intID] = LPC_PIN_IDS[p_pin]; 	// select which pin will cause the interrupts

    // XXX: using SI/CI ENF and ENR registers could probably save few instructions
    switch (p_mode) {
    case 0: {	// LOW level mode
        LPC_GPIO_PIN_INT ->ISEL |= (1 << p_intID);	// Set PMODE=level sensitive
        LPC_GPIO_PIN_INT ->IENR |= (1 << p_intID);	// Enable level interrupt.
        LPC_GPIO_PIN_INT ->IENF &= ~(1 << p_intID);	// Set active level LOW.
        break;
    }
    case 1: {	// HIGH level mode
        LPC_GPIO_PIN_INT ->ISEL |= (1 << p_intID);	// Set PMODE=level sensitive
        LPC_GPIO_PIN_INT ->IENR |= (1 << p_intID);	// Enable level interrupt.
        LPC_GPIO_PIN_INT ->IENF |= (1 << p_intID);	// Set active level HIGH.
        break;
    }
    case 2: {	// Edge CHANGE mode
        LPC_GPIO_PIN_INT ->ISEL &= ~(1 << p_intID);	// Set PMODE=edge sensitive
        LPC_GPIO_PIN_INT ->IENR |= (1 << p_intID);	// Enable rising edge.
        LPC_GPIO_PIN_INT ->IENF |= (1 << p_intID);	// Enable falling edge.
        break;
    }
    case 3: {	// RISING edge mode
        LPC_GPIO_PIN_INT ->ISEL &= ~(1 << p_intID);	// Set PMODE=edge sensitive
        LPC_GPIO_PIN_INT ->IENR |= (1 << p_intID);	// Enable rising edge.
        LPC_GPIO_PIN_INT ->IENF &= ~(1 << p_intID);	// Disable falling edge.
        break;
    }
    case 4: {	// FALLING edge mode
        LPC_GPIO_PIN_INT ->ISEL &= ~(1 << p_intID);	// Set PMODE=edge sensitive
        LPC_GPIO_PIN_INT ->IENR &= ~(1 << p_intID);	// Disable rising edge.
        LPC_GPIO_PIN_INT ->IENF |= (1 << p_intID);	// Enable falling edge.
        break;
    }
    }

    LPC_INTERRUPT_FUNCTION_TYPE[p_intID] = SFPFunction_getType(func);
    LPC_INTERRUPT_DOWNTIME[p_intID] = p_downtime;

    LPC_GPIO_PIN_INT->RISE = (1 << p_intID);	// Clear rising edge (sort of) flag
    LPC_GPIO_PIN_INT->FALL = (1 << p_intID);	// Clear falling edge (sort of) flag
    NVIC_SetPriority(p_intID, 3); // set lowest priority
    NVIC_EnableIRQ(p_intID);	// Enable interrupt. XXX: Luckily FLEX_INTx_IRQn == x, so it can be used this way, otherwise BE AWARE!

    return SFP_OK;
}
Exemplo n.º 11
0
SFPResult hcsr04Read(SFPFunction *msg) {
	if (SFPFunction_getArgumentCount(msg) != 2) return SFP_ERR_ARG_COUNT;

	if (SFPFunction_getArgumentType(msg, 0) != SFP_ARG_INT)
		return SFP_ERR_ARG_TYPE;
	if (SFPFunction_getArgumentType(msg, 1) != SFP_ARG_INT)
			return SFP_ERR_ARG_TYPE;

	uint8_t trigger = SFPFunction_getArgument_int32(msg, 0);
	uint8_t pulse = SFPFunction_getArgument_int32(msg, 1);
	uint32_t startTime = 0;
	uint32_t distance;

	if (trigger >= LPC_PIN_COUNT)
		return SFP_ERR_ARG_VALUE;
	if (pulse >= LPC_PIN_COUNT)
		return SFP_ERR_ARG_VALUE;

	uint8_t trigger_port = 0;
	uint8_t trigger_pinNum = LPC_PIN_IDS[trigger];
	if (trigger_pinNum > 23) {	// if not PIO0_0 to PIO0_23
		trigger_port = 1;
		trigger_pinNum -= 24;
	}

	uint8_t pulse_port = 0;
	uint8_t pulse_pinNum = LPC_PIN_IDS[pulse];
	if (pulse_pinNum > 23) {	// if not PIO0_0 to PIO0_23
		pulse_port = 1;
		pulse_pinNum -= 24;
	}

	/* Set the trigger as output, LOW */
	LPC_GPIO->CLR[trigger_port] = (1 << trigger_pinNum);
	*LPC_PIN_REGISTERS[trigger] &= ~LPC_PIN_MODE_MASK;	// Remove pull-up/down resistors
	LPC_GPIO->DIR[trigger_port] |= (1 << trigger_pinNum);

	/* Set the pulse as input, no resistors */
	*LPC_PIN_REGISTERS[pulse] &= ~LPC_PIN_MODE_MASK;	// Remove pull-up/down resistors
	*LPC_PIN_REGISTERS[pulse] |= (2 << 2) & LPC_PIN_MODE_MASK;;
	LPC_GPIO->DIR[pulse_port] &= ~(1 << pulse_pinNum);

	/* Send the trigger signal for 10us*/
	startTime = Time_getSystemTime_us();
	LPC_GPIO->SET[trigger_port] = (1 << trigger_pinNum);
	while ((Time_getSystemTime_us()-startTime) <= 10);
	LPC_GPIO->CLR[trigger_port] = (1 << trigger_pinNum);


	/* Wait for an answer */
	startTime = Time_getSystemTime_us();
	while (!(LPC_GPIO->PIN[pulse_port] & (1 << pulse_pinNum))) {
	    if ((Time_getSystemTime_us()-startTime) >= 25000) { // Timeout : 25ms
	   		break;
	   	}
	}

	/* Measure the pulse */
	startTime = Time_getSystemTime_us();
	while ((LPC_GPIO->PIN[pulse_port] & (1 << pulse_pinNum))) {
		if ((Time_getSystemTime_us()-startTime) >= 25000) { // Timeout : 25ms
		    break;
		}
    }

	distance = (Time_getSystemTime_us() - startTime) / 58;

	SFPFunction *outFunc = SFPFunction_new();

	if (outFunc == NULL) return SFP_ERR_ALLOC_FAILED;

	SFPFunction_setType(outFunc, SFPFunction_getType(msg));
	SFPFunction_setID(outFunc, UPER_FID_HCSR04);
	SFPFunction_setName(outFunc, UPER_FNAME_HCSR04);
	SFPFunction_addArgument_int32(outFunc, (distance < 25000 ? distance : 0));
	SFPFunction_send(outFunc, &stream);
	SFPFunction_delete(outFunc);

	return SFP_OK;
}