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.
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.