Pergunta

I'm trying to send some data from PC to ATmega328P chip through USBASP programmer.

It is able to transmit up to 4 bytes over SPI. These 4 bytes сan be set in USB Setup Packet (2 bytes for wValue and 2 bytes for wIndex). To enable SPI in ATmega328P I've connected USBASP Reset pin to SS. At PC side I'm using libusb to send USB Setup Packets.

ATmega328P code:

int main()
{
    char spiData = 0;

    // Enable SPI
    SPCR |= 1 << SPE;
    DDRB |= 1 << 4;

    // Main cycle
    while(1)
    {
        while(!(SPSR & (1 << SPIF))); // Wait for transmission end
        spiData = SPDR; // Read SPI Data Register
        // Do something with first byte

        while(!(SPSR & (1 << SPIF)));
        spiData = SPDR;
        // Do something with second byte

        while(!(SPSR & (1 << SPIF)));
        spiData = SPDR;
        // Do something with third byte

        while(!(SPSR & (1 << SPIF)));
        spiData = SPDR;
        // Do something with fourth byte
    }
    return 0;
}

PC code (C#):

static void Main(string[] args)
{
    // Find USBASP
    var device = UsbDevice.OpenUsbDevice(new UsbDeviceFinder(0x16C0, 0x05DC));

    // Set Clock and RESET pin to enable SPI
    int bytesTrasferred;
    var usbSetupPacket = new UsbSetupPacket(0xC0, 1, 0, 0, 0);
    device.ControlTransfer(ref usbSetupPacket, null, 0, out bytesTrasferred);

    // Send Setup Packets
    while (Console.ReadKey(true).Key == ConsoleKey.Enter)
    {
        byte[] buffer = new byte[4];
        usbSetupPacket = new UsbSetupPacket(0xC0, 3, 200, 200, 0);
        device.ControlTransfer(ref usbSetupPacket, buffer, 4, out bytesTrasferred);
        Console.WriteLine("Done. Return result: [{0}, {1}, {2}, {3}]", buffer[0], buffer[1], buffer[2], buffer[3]);
    }

    // Disable SPI
    usbSetupPacket = new UsbSetupPacket(0xC0, 2, 0, 0, 0);
    device.ControlTransfer(ref usbSetupPacket, null, 0, out bytesTrasferred);

    // Free resources
    device.Close();
    UsbDevice.Exit();
}

USBASP -> ATmega328P SPI communication works well, but it seems that data in wValue and wIndex fields of Setup Packet comes corrupted to USBASP, because I'm getting this output (while it should be constant - [0, 200, 0, 200]):

[0, 153, 0, 128]
[0, 136, 0, 128]
[1, 209, 1, 217]
[1, 128, 0, 145]
[1, 153, 0, 128]
[0, 145, 1, 209]
[1, 217, 1, 136]
[0, 209, 1, 209]
[1, 217, 1, 136]
so on...

Also I see these numbers on LED digit display connected to ATmega328P.

Can anyone explain that?

P.S. For programming purposes this USBASP works well.

Foi útil?

Solução

The problem was in SPI though. My ATmega328P was set by default to 8MHz internal clock with 1/8 divider, so it had 1MHz frequency which is too small for proper SPI communication. I fixed that by setting ATmega328P to external 16mHz crystal.

Outras dicas

You can also set the data transfer rate to 750kb in libusb or if that program does not support changing transfer rates, use a program such as avrdude which can do that.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top