I'm trying to send data to my STM32F427 MCU using the MCP2210 as the master in SPI communication. The MCP2210 acts as a HID device that converts USB data from the computer to an SPI signal, acting as the SPI MASTER, and can also receive data from others SPI slaves interfaces. To achieve this, I'm utilizing the hidapi library and following the instructions outlined in the MCP2210 datasheet.
In this setup, I have configured the terminal in Mode 0 with a bit rate of 1500. Additionally, I have connected the chip select (CS) pin to GP2.
To transmit information, I need to send data in blocks of 64 bytes and follow several commands.
Data sheet information:
Byte Index Meaning
0: 0x42 Transfer SPI Data – command code
1: The number of bytes to be transferred in this packet (from 0 to 60 inclusively)
2: 0x00 Reserved
3 0x00 Reserved
4-63 The SPI Data to be sent on the data transfer
With that, the expected response:
Byte Index Meaning
0 0x42 – Transfer SPI Data – echoes back the given command code
1 0x00 – SPI Data accepted – Command Completed Successfully – SPI data accepted
2 How many SPI received data bytes the chip is sending back to the host
3 0x10 – SPI Transfer Engine Status: SPI transfer finished – no more data to send
4-63 SPI received data bytes. The number of data bytes is specified at byte index 2
This is the code that I ´ve made for sending information to the masters device:
int main()
{
unsigned char data[64]; //buffer with the 64 bytes to send to the slave (transmission buffer)
unsigned char rdata[64]; //buffer with the 64 bytes of data recibed from the slave
// OPEN HID device
hid_device* dev = hid_open(0x04D8, 0x00DE, NULL);
if (!dev) {
std::cerr << "Error: can´t open HID" << std::endl;
return 1;
}
// Filling the transmission buffer:
data[0] = 0x00;
data[1] = 0x42; //Comand to iniciate SPI transmision
data[2] = 0x3C; // 60 bytes of data to send
data[3] = 0x00;
data[4] = 0x00;
data[5] = 0x01; // MSB: first Data send with value 0x01
for (int r = 6; r<64; r++) {
data[r] = 0xAA; //Values for the rest of the array (could be whatever)
}
res = hid_write(dev, data, 64);
res = hid_read(dev, rdata, 64);
if (res < 0) {
std::cerr << "can´t open HID" << std::endl;
}
std::cout << "HID response: \n";
//Code to print the recibed buffer:
for (int i = 0; i < 64; i++) {
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)rdata[i] << " ";
}
std::cout << std::endl;
printf("FIN \n");
hid_close(dev);
return 0;
}
Here is the slave code that I have written using STM32CubeIDE, just to test if the master can send and receive data from the slave:
#include "main.h"
SPI_HandleTypeDef hspi1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
#define SPI_TIMEOUT 10000
uint8_t txBuffer[60];
uint8_t rxBuffer[60];
int main(void)
{
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI1_Init();
uint8_t txBuffer[60];
uint8_t rxBuffer[60];
for (int i = 0; i < 60; i++) {
txBuffer[i] = 0xAA;
}
while (1)
{
HAL_SPI_TransmitReceive(&hspi1, txBuffer, rxBuffer, sizeof(txBuffer), SPI_TIMEOUT);
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_10);
if (rxBuffer[0] == 0x01){
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_15); //switch LED 1
}
}
}
This is the SPI initialisation function that I use. It´s automatically codified by the program after setting the correct parameters in the .ioc file of STM32CubeIDE.
static void MX_SPI1_Init(void)
{
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_SLAVE;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; //SPI Mode 0
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; //SPI Mode 0
hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
}
When the program reaches the line HAL_SPI_TransmitReceive(&hspi1, txBuffer, rxBuffer, sizeof(txBuffer), SPI_TIMEOUT), it waits until it receives an SPI signal from the master (unless the timeout occurs), and then the program continues. In the next line, I have added a LED toggling function to check if the slave detects the signal from the master. It appears to be working since the LEDs toggle before the timeout, indicating that a signal is being received. However, the problem lies in the data that is received in both directions.
As you can see, I am expecting to receive a 60-byte array filled with 0xAA in the master (without count with the 4 bytes of header for the response of the mcp2210), but in my master, I have only received an array of 60 bytes filled with 0xFF. Additionally, I am attempting to test if a single byte from the master arrives at the slave, I use the LED 1 on my board. According to my logic, if I receive 0x01 in rxBuffer, the LED should switch on, but it is´t work neither.
Therefore, my program is not functioning properly, and I am unable to send or receive data between the master and the slave.
Does anyone see any problems with this program or the way I'm working? I've prove everything I can and it dosen´t work.
Thanks by advance guys!