Esempio n. 1
0
PixelBone_Pixel::PixelBone_Pixel(uint16_t pixel_count)
    : pru0(pru_init(0)), num_pixels(pixel_count),
      buffer_size(pixel_count * sizeof(pixel_t)) {
  if (2 * buffer_size > pru0->ddr_size)
    die("Pixel data needs at least 2 * %zu, only %zu in DDR\n", buffer_size,
        pru0->ddr_size);

  ws281x = (ws281x_command_t *)pru0->data_ram;
  *(ws281x) = ws281x_command_t((unsigned)pixel_count);

  // Configure all of our output pins.
  pru_gpio(0, gpios0, 1, 0);

  // Initiate the PRU0 program
  pru_exec(pru0, "./ws281x.bin");

  // Watch for a done response that indicates a proper startup
  // TODO: timeout if it fails
  std::cout << "waiting for response from pru0... ";
  while (!ws281x->response)
    ;
  std::cout << "OK" << std::endl;
};
Esempio n. 2
0
int rtapi_app_main(void)
{
    hal_pru_generic_t *hpg;
    int retval;

    comp_id = hal_init("hal_pru_generic");
    if (comp_id < 0) {
        HPG_ERR("ERROR: hal_init() failed\n");
        return -1;
    }

    // Allocate HAL shared memory for state data
    hpg = hal_malloc(sizeof(hal_pru_generic_t));
    if (hpg == 0) {
        HPG_ERR("ERROR: hal_malloc() failed\n");
    hal_exit(comp_id);
    return -1;
    }

    // Clear memory
    memset(hpg, 0, sizeof(hal_pru_generic_t));

    // Initialize PRU and map PRU data memory
    if ((retval = pru_init(pru, prucode, disabled, hpg))) {
        HPG_ERR("ERROR: failed to initialize PRU\n");
        hal_exit(comp_id);
        return -1;
    }

    // Setup global state
    hpg->config.num_pwmgens  = num_pwmgens;
    hpg->config.num_stepgens = num_stepgens;
    hpg->config.num_encoders = num_encoders;
    hpg->config.comp_id      = comp_id;
    hpg->config.pru_period   = pru_period;
    hpg->config.name         = modname;
    hpg->config.halname      = halname;

    rtapi_print("num_pwmgens : %d\n",num_pwmgens);
    rtapi_print("num_stepgens: %d\n",num_stepgens);
    rtapi_print("num_encoders: %d\n",num_encoders);

    rtapi_print("Init pwm\n");
    // Initialize various functions and generate PRU data ram contents
    if ((retval = hpg_pwmgen_init(hpg))) {
        HPG_ERR("ERROR: pwmgen init failed: %d\n", retval);
        hal_exit(comp_id);
        return -1;
    }

    rtapi_print("Init stepgen\n");
    if ((retval = hpg_stepgen_init(hpg))) {
        HPG_ERR("ERROR: stepgen init failed: %d\n", retval);
        hal_exit(comp_id);
        return -1;
    }

    rtapi_print("Init encoder\n");
    if ((retval = hpg_encoder_init(hpg))) {
        HPG_ERR("ERROR: encoder init failed: %d\n", retval);
        hal_exit(comp_id);
        return -1;
    }

    if ((retval = hpg_wait_init(hpg))) {
        HPG_ERR("ERROR: global task init failed: %d\n", retval);
        hal_exit(comp_id);
        return -1;
    }

    if ((retval = export_pru(hpg))) {
        HPG_ERR("ERROR: var export failed: %d\n", retval);
        hal_exit(comp_id);
        return -1;
    }

    hpg_stepgen_force_write(hpg);
    hpg_pwmgen_force_write(hpg);
    hpg_encoder_force_write(hpg);
    hpg_wait_force_write(hpg);

    if ((retval = setup_pru(pru, prucode, disabled, hpg))) {
        HPG_ERR("ERROR: failed to initialize PRU\n");
        hal_exit(comp_id);
        return -1;
    }
    HPG_INFO("installed\n");
    hal_ready(comp_id);
    return 0;
}
Esempio n. 3
0
ledscape_t *
ledscape_init_with_modes(
	unsigned num_pixels,
	ledscape_output_mode_t pru0_mode,
	ledscape_output_mode_t pru1_mode
)
{
	pru_t * const pru0 = pru_init(0);
	pru_t * const pru1 = pru_init(1);

	const size_t frame_size = num_pixels * LEDSCAPE_NUM_STRIPS * 4;

	if (2 *frame_size > pru0->ddr_size)
		die("Pixel data needs at least 2 * %zu, only %zu in DDR\n",
			frame_size,
			pru0->ddr_size
		);

	ledscape_t * const leds = calloc(1, sizeof(*leds));

	*leds = (ledscape_t) {
		.pru0		= pru0,
		.pru1		= pru1,
		.num_pixels	= num_pixels,
		.frame_size	= frame_size,
		.pru0_mode  = pru0_mode,
		.pru1_mode  = pru1_mode,
		.ws281x_0	= pru0->data_ram,
		.ws281x_1	= pru1->data_ram
	};

	*(leds->ws281x_0) = *(leds->ws281x_1) = (ws281x_command_t) {
		.pixels_dma	= 0, // will be set in draw routine
		.command	= 0,
		.response	= 0,
		.num_pixels	= leds->num_pixels,
	};

	// Configure all of our output pins.
	for (unsigned i = 0 ; i < ARRAY_COUNT(gpios0) ; i++)
		pru_gpio(0, gpios0[i], 1, 0);
	for (unsigned i = 0 ; i < ARRAY_COUNT(gpios1) ; i++)
		pru_gpio(1, gpios1[i], 1, 0);
	for (unsigned i = 0 ; i < ARRAY_COUNT(gpios2) ; i++)
		pru_gpio(2, gpios2[i], 1, 0);
	for (unsigned i = 0 ; i < ARRAY_COUNT(gpios3) ; i++)
		pru_gpio(3, gpios3[i], 1, 0);

	// Initiate the PRU0 program
	const char* pru0_program_filename;
	switch (pru0_mode) {
		case NOP: pru0_program_filename = "./nop_0.bin"; break;
		case WS281x: pru0_program_filename = "./ws281x_0.bin"; break;
		case DMX: pru0_program_filename = "./dmx_0.bin"; break;
		case WS2801: pru0_program_filename = "./ws2801_0.bin"; break;
		case WS2801_NEWPINS: pru0_program_filename = "./ws2801_newpins_0.bin"; break;
		default:
			warn("Invalid PRU0 Mode.");
			pru0_program_filename = "./ws281x_0.bin";
	}
	pru_exec(pru0, pru0_program_filename);

	// Watch for a done response that indicates a proper startup
	// \todo timeout if it fails
	fprintf(stdout, "String PRU0 with %s... ", pru0_program_filename);
	while (!leds->ws281x_0->response);
	printf("OK\n");


	// Initiate the PRU1 program
	const char* pru1_program_filename;
	switch (pru1_mode) {
		case NOP: pru1_program_filename = "./nop_1.bin"; break;
		case WS281x: pru1_program_filename = "./ws281x_1.bin"; break;
		case DMX:
			warn("PRU1 does not currently support DMX.");
			pru1_program_filename = "./ws281x_1.bin";
		break;
		case WS2801: pru1_program_filename = "./ws2801_1.bin"; break;
		case WS2801_NEWPINS: pru1_program_filename = "./ws2801_newpins_1.bin"; break;
		default:
			pru1_program_filename = "./ws281x_1.bin";
			warn("Invalid PRU1 Mode.");
	}
	pru_exec(pru1, pru1_program_filename);

	// Watch for a done response that indicates a proper startup
	// \todo timeout if it fails
	fprintf(stdout, "String PRU1 with %s... ", pru1_program_filename);
	while (!leds->ws281x_1->response);
	printf("OK\n");

	return leds;
}


void
ledscape_close(
	ledscape_t * const leds
)
{
	// Signal a halt command
	leds->ws281x_0->command = 0xFF;
	leds->ws281x_1->command = 0xFF;
	pru_close(leds->pru0);
	pru_close(leds->pru1);
}


void
ledscape_set_color(
	ledscape_frame_t * const frame,
	uint8_t strip,
	uint16_t pixel,
	uint8_t r,
	uint8_t g,
	uint8_t b
)
{
	ledscape_pixel_t * const p = &frame[pixel].strip[strip];
	p->r = r;
	p->g = g;
	p->b = b;
}