J'ai donc essayé d'utiliser le signal NSS matériel avec la bibliothèque HAL, mais je ne trouve aucune fonction pour faire en sorte que la broche NSS ait un niveau bas ou élevé. J'ai également essayé de trouver la réponse dans la documentation HAL, mais il n'y a pas non plus d'informations. Tous les exemples sur Internet contiennent uniquement des logiciels NSS. Comment est-on censé utiliser le matériel NSS?
Quelque part, j'ai lu que NSS est conduit bas tant que le maître SPI est activé et poussé à nouveau si le maître SPI est désactivé. J'ai essayé en utilisant le Bibliothèque HAL (Cube/CubeMX) de ST avec un STM32L476 et polling SPI1. L'initialisation avant et la réinitialisation après la transmission n'ont PAS défini la broche NSS - mais ont pris beaucoup de temps:
Structure init:
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
hspi1.Init.CLKPhase = SPI_PHASE_2Edge;
hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 7;
hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;
hspi1.Init.NSSPMode = SPI_NSS_Pulse_DISABLE;
Séquence de transmission:
HAL_SPI_Init( &hspi1 );
HAL_SPI_TransmitReceive( &hspi1, btx, brx, l, 5 ); // timeout 5msec;
while( hspi1.State == HAL_SPI_STATE_BUSY ); // wait for xmission complete
HAL_SPI_DeInit( &hspi1 );
J'ai donc décidé de définir manuellement la broche à l'aide de GPIO (en utilisant SPI_NSS_SOFT en init):
HAL_GPIO_WritePin( NSS1_GPIO_Port, NSS1_Pin, GPIO_PIN_RESET ); // NSS1 low
HAL_SPI_TransmitReceive( &hspi1, btx, brx, l, 5 ); // timeout 5msec;
while( hspi1.State == HAL_SPI_STATE_BUSY ); // wait xmission complete
HAL_GPIO_WritePin( NSS1_GPIO_Port, NSS1_Pin, GPIO_PIN_SET ); // NSS1 high
J'ai utilisé le blocage de la transmission (non DMA ou Interruption) car il était assez rapide et aucune autre tâche n'était en attente. DMA s'est avérée prendre un temps inacceptablement plus long pour envoyer uniquement 24 octets à 20 MHz. L'informatique serait une alternative acceptable.
Autant que je puisse voir dans le chapitre 38.4.12/13 du manuel STM32L4xx, le NSS automatique monte haut après chaque transmission d'octet/mot et n'est donc pas bien utilisable pour les flux plus longs maintenant NSS bas pour toute la transmission.
Vous pouvez utiliser la broche NSS comme GPIO standard et le piloter avec une routine d'interruption.Vous devez le faire par logiciel.Tout d'abord, mettez le Nss bas puis envoyez votre trame (HAL_SPI_Transmit) Une fois que l'esclave a obtenu toute la trame, utilisez le HAL_SPI_RxCpltCallback et mettre le Nss haut dans cette interruption.
N'oubliez pas de connecter la broche GPIO à la broche Nss sur l'esclave.
La broche NSS peut nécessiter une résistance de rappel si HiZ [non documenté]
Consultez le manuel de référence de votre puce STM32. Je ne sais pas s'ils sont tous les mêmes, mais selon celui pour le mien (STM32WB55xx) et celui auquel j'ai pu trouver un lien Web public vers ( STM32F ) ...
Voir la description fonctionnelle SPI pour la gestion des broches NSS (section 28.5.5 pour le document STM32F0 auquel je suis lié), où elle décrit trois modes:
Gestion NSS logicielle (SPIx_CR1 registre SSM bit = 1). Les informations internes de sélection d'esclave sont pilotées en interne par le bit SSI dans le registre SPIx_CR1. La broche NSS externe est gratuite pour les applications.
Gestion du matériel NSS (bit SSM = 0). Cela a deux configurations possibles en fonction du bit SSOE dans le registre SPIx_CR1:
En regardant les en-têtes de mon SoC, le mode doux est SSM = 1 (gestion du logiciel NSS). Le mode de sortie matérielle est SSM = 0 et SSOE = 1 (activation de la sortie NSS). Le mode d'entrée matérielle est entièrement à zéro (désactivation de la sortie NSS).
Si vous utilisez le mode de sortie matérielle, vous pouvez également consulter le mode NSS Pulse (section 28.5.12 du document STM32F0 auquel j'ai lié). Il décrit (avec un chronogramme) comment le système laissera NSS bas la plupart du temps, le pulsant haut entre les trames de données. Si votre appareil utilise NSS/CS pour synchroniser les trames de données, cela peut être utile. Ou peut-être pas, si votre appareil réagit au NSS qui monte haut en abandonnant l'opération en cours, car le texte semble indiquer qu'il pulsera le NSS entre chaque mot que vous transférez, pas entre les tampons.
Malheureusement, cela ne ressemble pas à l'implémentation la plus flexible. Selon votre application, il peut être plus facile de le laisser en mode logiciel et de simplement basculer la broche NSS via les GPIO.