in reply to Re: Bit string manipulation made easy with Bit::Manip
in thread Bit string manipulation made easy with Bit::Manip

Thanks for the superb feedback based on the appreciated work you did reading through the docs and playing with the code!

I'm just prototyping a new chip using this software almost exclusively for my bit-banging just to test how it works at the moment. I've found a few things that irk me that I'll be looking at changing, but after I'm done with the guts of this hardware and I have a bit schematic ready to write in C, I'll carefully review your node here and consider with what I've found and most likely do another update.

As it stands, I'm getting some Testers failures on v5.6 anyhow (import wasn't exported from Exporter back then, so I think I need to declare a specific version of that dist, so a fix is in order anyhow. As an aside, I shouldn't have gone to v1.xx so quickly. Normally I give myself some time to ensure no API changes occur. It is what it is.

Replies are listed 'Best First'.
Re^3: Bit string manipulation made easy with Bit::Manip
by stevieb (Canon) on Jan 31, 2017 at 22:43 UTC

    First full IC prototype using Perl, with the Bit::Manip software for bit banging, worked out quite well. Now I'm just finishing up the C code that will take over the work, and publish the distribution for the MCP4922 (well, the MCP49x2) digital to analog converters.

    update: breadboard layout and schematic used for the prototype testing./update

    After that's complete, I'll be making some of the suggested updates to Bit::Manip. Again, thanks for the feedback everyone!

    use warnings; use strict; use feature 'say'; use Bit::Manip qw(:all); use RPi::WiringPi; use RPi::WiringPi::Constant qw(:all); my $spi_chan = 0; my $pi = RPi::WiringPi->new; my $adc = $pi->adc; my $spi = $pi->spi($spi_chan); my $cs_pin = $pi->pin(18); my $shdn_pin = $pi->pin(6); # light up some pins per the datasheet # device channel select (CS) to HIGH, in case the # device started it as LOW. In this case, we # bit-bang the CS pin, instead of using the # hardware SPI $cs_pin->mode(OUTPUT); $cs_pin->write(HIGH); # device 'shutdown' (SHDN) pin we'll tie to HIGH, # when tied to HIGH, means all DACs active $shdn_pin->mode(OUTPUT); $shdn_pin->write(HIGH); # show the current voltage output % on both DAC # channels before we begin say $adc->percent(0); say $adc->percent(1); # dac 0 say "\nDAC 0...\n"; dac_write(0, [0b1111, 0b11111111]); say "dacA: " . $adc->percent(0) . "%"; dac_write(0, [0b0111, 0b0]); say "dacA: " . $adc->percent(0) . "%"; dac_write(0, [0b0, 0b0]); say "dacA: " . $adc->percent(0) . "%"; # dac 1 say "\nDAC 1...\n"; dac_write(1, [0b1111, 0b11111111]); say "dacB: " . $adc->percent(1) . "%"; dac_write(1, [0b0111, 0b0]); say "dacB: " . $adc->percent(1) . "%"; dac_write(1, [0b0, 0b0]); say "dacB: " . $adc->percent(1) . "%"; sub dac_write { my ($dac, $data) = @_; die "\$dac param must be 0 or 1\n" if $dac != 0 && $dac != 1; # init the register my $register = [0, 0]; # DAC (bit 7) (a/b == 0/1) we're writing to $register->[0] = bit_set($register->[0], 7, 1, $dac); # BUFFERING (bit 6) == 0 $register->[0] = bit_set($register->[0], 6, 1, 0); # GAIN (bit 5) == 1 $register->[0] = bit_on($register->[0], 5); # SHDN (shutdown) (bit 4) == 1 $register->[0] = bit_set($register->[0], 4, 1, 1); # DATA (bits 3-0) $register->[0] = bit_set($register->[0], 0, 4, $data->[0]); say "byte1: ".bit_bin($register->[0]); # DATA byte 2 $register->[1] = bit_set($register->[1], 0, 8, $data->[1]); say "byte2: ".bit_bin($register->[1]); # drop chip select to LOW to start conversation with the DAC $cs_pin->write( LOW ); # write our bytes to the SPI bus $spi->rw($register, 2); # go HIGH to tell the IC we're done clocking in bits $cs_pin->write( HIGH ); } $pi->cleanup;

    output:

    0.00 0.00 DAC 0... byte1: 111111 byte2: 11111111 dacA: 99.94% byte1: 110111 byte2: 0 dacA: 43.76% byte1: 110000 byte2: 0 dacA: 0.00% DAC 1... byte1: 10111111 byte2: 11111111 dacB: 100.00% byte1: 10110111 byte2: 0 dacB: 43.70% byte1: 10110000 byte2: 0 dacB: 0.00%