#include <dos.h>
#include <stdio.h>
#include <conio.h>
#define PORT1 0x2E8 /* Port Address Goes Here */
/* Defines Serial Ports Base Address */
/* COM4 0x2E8 */
#define INTVECT 0x0B /* Com Port's IRQ here */
/* (Must also change PIC setting) */
int bufferin = 0;
int bufferout = 0;
char ch;
char buffer[1025];
void interrupt PORT1INT() /* Interrupt Service Routine (ISR) for PORT1 */
{
int c;
do {
c = inportb(PORT1 + 5);
if (c & 1) {
buffer[bufferin] = inportb(PORT1);
bufferin++;
if (bufferin == 1024) bufferin = 0;
}
} while (c & 1);
outportb(0x20, 0x20);
}
void main(void)
{
int c;
//outportb(PORT1 + 1, 0); /* Turn off interrupts - Port1 */
//oldport1isr = getvect(INTVECT); /* Save old Interrupt Vector for */
/* later recovery */
setvect(INTVECT, PORT1INT); /* Set Interrupt Vector Entry */
/* COM1 - 0x0C */
/* COM2 - 0x0B */
/* COM3 - 0x0C */
/* COM4 - 0x0B */
outportb(PORT1 +3 , 0x80); /* SET DLAB ON */
outportb(PORT1 +0, 0x03); /* Set Baud rate - Divisor Latch Low Byte */
/* Default 0x03 = 38,400 BPS */
/* 0x01 = 115,200 BPS */
/* 0x02 = 56,700 BPS */
/* 0x06 = 19,200 BPS */
/* 0x0C = 9,600 BPS */
/* 0x18 = 4,800 BPS */
/* 0x30 = 2,400 BPS */
outportb(PORT1 + 1, 0x00); /* Set Baud rate - Divisor Latch High Byte */
outportb(PORT1 + 3, 0x03); /* 8 Bits, No Parity, 1 Stop Bit */
outportb(PORT1 + 2, 0xC7); /* FIFO Control Register */
outportb(PORT1 + 4, 0x0B); /* Turn on DTR, RTS, and OUT2 */
outportb(0x21, (inportb(0x21) & 0xF7)); /* Set Programmable Interrupt */
/* Controller */
/* COM1 (IRQ4) - 0xEF */
/* COM2 (IRQ3) - 0xF7 */
/* COM3 (IRQ4) - 0xEF */
/* COM4 (IRQ3) - 0xF7 */
outportb(PORT1 + 1, 0x01); /* Interrupt when data received */
printf("\nSample Comm's Program. Press ESC to quit \n");
do {
if (bufferin != bufferout){
ch = buffer[bufferout];
bufferout++;
if (bufferout == 1024) bufferout = 0;
printf("%c", ch);
}
if (kbhit()){
c = getch();
outportb(PORT1, c);
}
} while
(c != 27);
outportb(PORT1 + 1, 0); /* Turn off interrupts - Port1 */
outportb(0x21, (inportb(0x21) | 0x08)); /* MASK IRQ using PIC */
/* COM1 (IRQ4) - 0x10 */
/* COM2 (IRQ3) - 0x08 */
/* COM3 (IRQ4) - 0x10 */
/* COM4 (IRQ3) - 0x08 */
setvect(INTVECT, oldport1isr); /* Restore old interrupt vector */
}
So I have to send some data from an UART to an UART using COM4 Serial Port, I have this small program here as an example but can't figure out why I can't compile it in Visual Studion ( C++ Win32 Project )
Any ideas? I also have to implement an timer with RQ3.
It can't compile because access to the hardware is managed by the OS. Your example states in the very first line which OS it applies to, and it's not Windows.
As for your second claim, you don't. IRQ3 is not used for timers in Windows programs. There are plenty of answers about timers already on StackOverflow, so check that first.
Related
I would like to merge two pieces of code and I'm not sure how I should go about it. The first code is for Bluetooth and the second is for an NFC reader. By simply just adding the script the bottom of the other it gives me the error 'Serial' does not name a type. Although it runs perfectly fine on its own. They both need to be running at the same time as well. Any thoughts?
Bluetooth
#include <SoftwareSerial.h>
#include <ArduinoBlue.h>
const unsigned long BAUD_RATE = 9600;
// The bluetooth tx and rx pins must be supported by software serial.
// Visit https://www.arduino.cc/en/Reference/SoftwareSerial for unsupported pins.
// Bluetooth TX -> Arduino D8
const int BLUETOOTH_TX = 8;
// Bluetooth RX -> Arduino D7
const int BLUETOOTH_RX = 7;
int prevThrottle = 49;
int prevSteering = 49;
int throttle, steering, sliderVal, button, sliderId;
SoftwareSerial bluetooth(BLUETOOTH_TX, BLUETOOTH_RX);
ArduinoBlue phone(bluetooth); // pass reference of bluetooth object to ArduinoBlue constructor
// Setup code runs once after program starts.
void setup() {
// Start serial communications.
// The baud rate must be the same for both the serial and the bluetooth.
Serial.begin(BAUD_RATE);
bluetooth.begin(BAUD_RATE);
delay(100);
Serial.println("setup complete");
}
// Put your main code here, to run repeatedly:
void loop() {
// ID of the button pressed pressed.
button = phone.getButton();
// Returns the text data sent from the phone.
// After it returns the latest data, empty string "" is sent in subsequent.
// calls until text data is sent again.
String str = phone.getText();
// Display button data whenever its pressed.
if (button == 1) {
Serial.print("Door Locked");
}
// Display button data whenever its pressed.
if (button == 0) {
Serial.print("Door Unlocked");
}
}
NFC
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
// Number of known default keys (hard-coded)
// NOTE: Synchronize the NR_KNOWN_KEYS define with the defaultKeys[] array
#define NR_KNOWN_KEYS 8
// Known keys, see: https://code.google.com/p/mfcuk/wiki/MifareClassicDefaultKeys
byte knownKeys[NR_KNOWN_KEYS][MFRC522::MF_KEY_SIZE] = {
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // FF FF FF FF FF FF = factory default
{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}, // A0 A1 A2 A3 A4 A5
{0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5}, // B0 B1 B2 B3 B4 B5
{0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd}, // 4D 3A 99 C3 51 DD
{0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a}, // 1A 98 2C 7E 45 9A
{0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}, // D3 F7 D3 F7 D3 F7
{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, // AA BB CC DD EE FF
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // 00 00 00 00 00 00
};
/*
* Initialize.
*/
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Try the most used default keys to print block 0 of a MIFARE PICC."));
}
/*
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
/*
* Try using the PICC (the tag/card) with the given key to access block 0.
* On success, it will show the key details, and dump the block data on Serial.
*
* #return true when the given key worked, false otherwise.
*/
bool try_key(MFRC522::MIFARE_Key *key)
{
bool result = false;
byte buffer[18];
byte block = 0;
MFRC522::StatusCode status;
// Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
// Serial.print(F("PCD_Authenticate() failed: "));
// Serial.println(mfrc522.GetStatusCodeName(status));
return false;
}
// Read block
byte byteCount = sizeof(buffer);
status = mfrc522.MIFARE_Read(block, buffer, &byteCount);
if (status != MFRC522::STATUS_OK) {
// Serial.print(F("MIFARE_Read() failed: "));
// Serial.println(mfrc522.GetStatusCodeName(status));
}
else {
// Successful read
result = true;
Serial.print(F("Success with key:"));
dump_byte_array((*key).keyByte, MFRC522::MF_KEY_SIZE);
Serial.println();
// Dump block data
Serial.print(F("Block ")); Serial.print(block); Serial.print(F(":"));
dump_byte_array(buffer, 16);
Serial.println();
}
Serial.println();
mfrc522.PICC_HaltA(); // Halt PICC
mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD
return result;
}
/*
* Main loop.
*/
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
return;
// Show some details of the PICC (that is: the tag/card)
Serial.print(F("Card UID:"));
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
// Try the known default keys
MFRC522::MIFARE_Key key;
for (byte k = 0; k < NR_KNOWN_KEYS; k++) {
// Copy the known key into the MIFARE_Key structure
for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++) {
key.keyByte[i] = knownKeys[k][i];
}
// Try the key
if (try_key(&key)) {
// Found and reported on the key and block,
// no need to try other keys for this PICC
break;
}
// http://arduino.stackexchange.com/a/14316
if ( ! mfrc522.PICC_IsNewCardPresent())
break;
if ( ! mfrc522.PICC_ReadCardSerial())
break;
}
}
Merged Code (with error 'Serial' does not name a type.)
#include <SoftwareSerial.h>
#include <ArduinoBlue.h>
#include <SPI.h>
#include <MFRC522.h>
const unsigned long BAUD_RATE = 9600;
// The bluetooth tx and rx pins must be supported by software serial.
// Visit https://www.arduino.cc/en/Reference/SoftwareSerial for unsupported pins.
// Bluetooth TX -> Arduino D8
const int BLUETOOTH_TX = 8;
// Bluetooth RX -> Arduino D7
const int BLUETOOTH_RX = 7;
int prevThrottle = 49;
int prevSteering = 49;
int throttle, steering, sliderVal, button, sliderId;
SoftwareSerial bluetooth(BLUETOOTH_TX, BLUETOOTH_RX);
ArduinoBlue phone(bluetooth); // pass reference of bluetooth object to ArduinoBlue constructor
// Setup code runs once after program starts.
void setup() {
// Start serial communications.
// The baud rate must be the same for both the serial and the bluetooth.
Serial.begin(BAUD_RATE);
bluetooth.begin(BAUD_RATE);
delay(100);
Serial.println("setup complete");
}
// Put your main code here, to run repeatedly:
void loop() {
// ID of the button pressed pressed.
button = phone.getButton();
// Returns the text data sent from the phone.
// After it returns the latest data, empty string "" is sent in subsequent.
// calls until text data is sent again.
String str = phone.getText();
// Display button data whenever its pressed.
if (button == 1) {
Serial.print("Door Locked");
}
// Display button data whenever its pressed.
if (button == 0) {
Serial.print("Door Unlocked");
}
}
#define RST_PIN 9 // Configurable, see typical pin layout above
#define SS_PIN 10 // Configurable, see typical pin layout above
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
// Number of known default keys (hard-coded)
// NOTE: Synchronize the NR_KNOWN_KEYS define with the defaultKeys[] array
#define NR_KNOWN_KEYS 8
// Known keys, see: https://code.google.com/p/mfcuk/wiki/MifareClassicDefaultKeys
byte knownKeys[NR_KNOWN_KEYS][MFRC522::MF_KEY_SIZE] = {
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // FF FF FF FF FF FF = factory default
{0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5}, // A0 A1 A2 A3 A4 A5
{0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5}, // B0 B1 B2 B3 B4 B5
{0x4d, 0x3a, 0x99, 0xc3, 0x51, 0xdd}, // 4D 3A 99 C3 51 DD
{0x1a, 0x98, 0x2c, 0x7e, 0x45, 0x9a}, // 1A 98 2C 7E 45 9A
{0xd3, 0xf7, 0xd3, 0xf7, 0xd3, 0xf7}, // D3 F7 D3 F7 D3 F7
{0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff}, // AA BB CC DD EE FF
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // 00 00 00 00 00 00
};
/*
* Initialize.
*/
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Try the most used default keys to print block 0 of a MIFARE PICC."));
}
/*
* Helper routine to dump a byte array as hex values to Serial.
*/
void dump_byte_array(byte *buffer, byte bufferSize) {
for (byte i = 0; i < bufferSize; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
}
/*
* Try using the PICC (the tag/card) with the given key to access block 0.
* On success, it will show the key details, and dump the block data on Serial.
*
* #return true when the given key worked, false otherwise.
*/
bool try_key(MFRC522::MIFARE_Key *key)
{
bool result = false;
byte buffer[18];
byte block = 0;
MFRC522::StatusCode status;
// Serial.println(F("Authenticating using key A..."));
status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
// Serial.print(F("PCD_Authenticate() failed: "));
// Serial.println(mfrc522.GetStatusCodeName(status));
return false;
}
// Read block
byte byteCount = sizeof(buffer);
status = mfrc522.MIFARE_Read(block, buffer, &byteCount);
if (status != MFRC522::STATUS_OK) {
// Serial.print(F("MIFARE_Read() failed: "));
// Serial.println(mfrc522.GetStatusCodeName(status));
}
else {
// Successful read
result = true;
Serial.print(F("Success with key:"));
dump_byte_array((*key).keyByte, MFRC522::MF_KEY_SIZE);
Serial.println();
// Dump block data
Serial.print(F("Block ")); Serial.print(block); Serial.print(F(":"));
dump_byte_array(buffer, 16);
Serial.println();
}
Serial.println();
mfrc522.PICC_HaltA(); // Halt PICC
mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD
return result;
}
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if ( ! mfrc522.PICC_IsNewCardPresent())
return;
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial())
return;
// Show some details of the PICC (that is: the tag/card)
Serial.print(F("Card UID:"));
dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size);
Serial.println();
Serial.print(F("PICC type: "));
MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
Serial.println(mfrc522.PICC_GetTypeName(piccType));
// Try the known default keys
MFRC522::MIFARE_Key key;
for (byte k = 0; k < NR_KNOWN_KEYS; k++) {
// Copy the known key into the MIFARE_Key structure
for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++) {
key.keyByte[i] = knownKeys[k][i];
}
// Try the key
if (try_key(&key)) {
// Found and reported on the key and block,
// no need to try other keys for this PICC
break;
}
// http://arduino.stackexchange.com/a/14316
if ( ! mfrc522.PICC_IsNewCardPresent())
break;
if ( ! mfrc522.PICC_ReadCardSerial())
break;
}
}
The error appears because the following lines are not inside a function declaration. The compiler is expecting a variable declaration and instead sees the call to Serial.begin(). To fix that problem, move these lines into the setup() function from where they currently are:
Serial.begin(9600); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card
Serial.println(F("Try the most used default keys to print block 0 of a MIFARE PICC."));
Of course, there should be only one Serial.begin() call in your setup() function, not two, and, as a commenter pointed out, you should merge the code from your two loop() functions into a single loop() function.
as the title suggests im trying to make two STM boards talk to each other. The problem is, is the master can send, and the slave can receive. But the slave cant transmit anything. I checked it on an analyzer and the only thing the slave is sending is 0xFF.
(Chip Select is in software)
So im looking for help, or maybe an explanation.
MASTER:
#include "main.h"
#include "stm32f1xx_hal.h"
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "string.h"
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi2;
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI2_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
void print(char * buffer)
{
HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
}
/* USER CODE END 0 */
/**
* #brief The application entry point.
*
* #retval None
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
for(uint8_t i = 0; ;i++)
{
int result = 0;
GPIOB->BSRR = (1 << 12);
HAL_SPI_TransmitReceive(&hspi2, (uint8_t *)&i, (uint8_t*)&result, 2, HAL_MAX_DELAY);
GPIOB->BRR = (1 << 12);
if (result != (i - 1))
{
print("nop");
}
HAL_Delay(10);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* SPI2 init function */
static void MX_SPI2_Init(void)
{
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_MASTER;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* USART1 init function */
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_5, GPIO_PIN_SET);
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : PB10 */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : PB12 PB5 */
GPIO_InitStruct.Pin = GPIO_PIN_12|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
SLAVE:
#include "main.h"
#include "stm32f1xx_hal.h"
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "string.h"
/* USER CODE END Includes */
/* Private variables ---------------------------------------------------------*/
SPI_HandleTypeDef hspi2;
UART_HandleTypeDef huart1;
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI2_Init(void);
static void MX_USART1_UART_Init(void);
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE END PFP */
/* USER CODE BEGIN 0 */
void print(char * buffer)
{
HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), HAL_MAX_DELAY);
}
/* USER CODE END 0 */
/**
* #brief The application entry point.
*
* #retval None
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration----------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_SPI2_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
SPI2->CR1 |= 1UL << 9;
SPI2->CR1 |= 1UL << 8;
while (1)
{
if(GPIOB->IDR & (1 << 10))
{
SPI2->CR1 &= ~(1UL << 8);
HAL_SPI_TransmitReceive(&hspi2, (uint8_t *)&output,(uint8_t*)&input, 1, HAL_MAX_DELAY);
output = input;
SPI2->CR1 |= 1UL << 8;
}
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* USER CODE END 3 */
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
/* SPI2 init function */
static void MX_SPI2_Init(void)
{
/* SPI2 parameter configuration*/
hspi2.Instance = SPI2;
hspi2.Init.Mode = SPI_MODE_SLAVE;
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi2.Init.NSS = SPI_NSS_SOFT;
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi2.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi2) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/* USART1 init function */
static void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
static void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, RowPins_Pin|RowPinsA9_Pin|RowPinsA10_Pin|RowPinsA11_Pin
|RowPinsA12_Pin, GPIO_PIN_SET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
/*Configure GPIO pin : PC13 */
GPIO_InitStruct.Pin = GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : ColumnPins_Pin ColumnPinsA1_Pin ColumnPinsA2_Pin ColumnPinsA3_Pin
ColumnPinsA4_Pin ColumnPinsA5_Pin ColumnPinsA6_Pin */
GPIO_InitStruct.Pin = ColumnPins_Pin|ColumnPinsA1_Pin|ColumnPinsA2_Pin|ColumnPinsA3_Pin
|ColumnPinsA4_Pin|ColumnPinsA5_Pin|ColumnPinsA6_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PB10 */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLDOWN;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : RowPins_Pin RowPinsA9_Pin RowPinsA10_Pin RowPinsA11_Pin
RowPinsA12_Pin */
GPIO_InitStruct.Pin = RowPins_Pin|RowPinsA9_Pin|RowPinsA10_Pin|RowPinsA11_Pin
|RowPinsA12_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pin : PB5 */
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
Master has to send data and generate the clock for the slave. So if you expecting something to be received from the slave you need to send the same number of dummy data.
This is how the SPI works.
The master to receive data must transmit at the same time. Slave to transmit has to wait for the clock signal - and it is generated by the master when transmitting.
BTW HAL SPI implementation (USART as well) is horrible. Use bare registers instead.
I want to get "2 signals" when I read an audio file. I know that I must use the FFmpeg function av_read_frame, but I have just that I call "1 signal". How can I have multiple signals to treat each signal in different way ?
My code is like that :
while (av_read_frame(pFormatCtx, packet) >= 0)
{
/* AVPacket == Audio */
if (packet->stream_index == audioStream)
{
/* Décodage des packets */
ret = avcodec_decode_audio4(pCodecCtx, pFrame, &got_picture, packet);
if (ret < 0)
{
fprintf(stderr, "%s\n", "Error in decoding audio frame");
return (-1);
}
if (got_picture > 0)
{
/* Convertissage de l'audio */
swr_convert(au_convert_ctx, &out_buffer, MAX_AUDIO_FRAME_SIZE, (const uint8_t **)pFrame->data, pFrame->nb_samples);
#if 1
/* Affichage des informations dans la console */
printf("Index : %5d\t Points : %lld\t Packet size : %d\n", index, packet->pts, packet->size);
#endif /* 1 */
#if OUTPUT_PCM
/* Fonction pour écrire dans le fichier */
fwrite(out_buffer, 1, out_buffer_size, pFile);
#endif /* OUTPUT_PCM */
/* Incrémentation */
index = index + 1;
}
#if USE_SDL
while (audio_len > 0)
SDL_Delay(1);
/* Attribution des valeurs avec les variables globales */
audio_chunk = (Uint8 *)out_buffer;
audio_len = out_buffer_size;
audio_pos = audio_chunk;
SDL_PauseAudio(0);
#endif /* USE_SDL */
}
/* Libérer la structure AVPacket */
av_free_packet(packet);
}
Simple problem. When I write to /dev/ttyS1, it does not flush it immediately. This is probably something to do with my initialization of serial port... But I can not figure it out! My code is like this:
#define BAUDRATE B115200
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1 /* POSIX compliant source */
#define FALSE 0
#define TRUE 1
volatile int STOP = FALSE;
void signal_handler_IO(int status); /* definition of signal handler */
int wait_flag = TRUE; /* TRUE while no signal received */
int main()
{
int fd, c, res;
struct termios oldtio, newtio;
struct sigaction saio; /* definition of signal action */
char buf[255];
/* open the device to be non-blocking (read will return immediatly) */
fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0) {
perror(MODEMDEVICE);
exit(-1);
}
/* install the signal handler before making the device asynchronous */
saio.sa_handler = signal_handler_IO;
//saio.sa_mask = 0;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
sigaction(SIGIO, &saio, NULL);
/* allow the process to receive SIGIO */
fcntl(fd, F_SETOWN, getpid());
/* Make the file descriptor asynchronous (the manual page says only
O_APPEND and O_NONBLOCK, will work with F_SETFL...) */
fcntl(fd, F_SETFL, FASYNC);
tcgetattr(fd, &oldtio); /* save current port settings */
/* set new port settings for canonical input processing */
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR | ICRNL;
newtio.c_oflag = 0;
newtio.c_lflag = ICANON;
newtio.c_cc[VMIN] = 1;
newtio.c_cc[VTIME] = 0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);
int i = 0;
/* loop while waiting for input. normally we would do something
useful here */
while (1) {
printf(".\n");
usleep(100000);
//tcflush(fd, TCOFLUSH);
//tcflush(fd, TCIOFLUSH);
i++;
if (i == 20) {
// ------------------ write to serial ----------------------
int n = write(fd, "ATZ\n", 4);
if (n < 0)
fputs("write() of 4 bytes failed!\n", stderr);
}
/* after receiving SIGIO, wait_flag = FALSE, input is available
and can be read */
if (wait_flag == FALSE ) {
res = read(fd, buf, 255);
buf[res] = 0;
printf(":%s:%d\n", buf, res);
wait_flag = TRUE; /* wait for new input */
}
}
/* restore old port settings */
tcsetattr(fd, TCSANOW, &oldtio);
}
void signal_handler_IO(int status) {
printf("received SIGIO signal.\n");
wait_flag = FALSE;
}
Any idea?
You have enabled CTS hardware flow control by setting CRTSCTS. That means that if the if the CTS input to the UART is not active, the UART should refrain from transmitting.
You might want to have a look through the termios man page in general.
I do not think this is a solution, but adding:
tcflush(fd, TCIOFLUSH); // clear buffer
to clear the buffer seem to do the trick. However, there should be some more elegant and proper solution.
Since "flush" can mean either clear buffer or wait until all bytes are sent, here's quotation from https://linux.die.net/man/3/tcdrain
tcdrain() waits until all output written to the object referred to by fd has been transmitted.
tcflush() discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of queue_selector
So,
tcdrain(fd); // Wait until transmission ends
tcflush(fd, TCOFLUSH); // Clear write buffer
I'm running Ubuntu 9.10 and I seem to be having trouble with termios.
So I can start minicom open the serial port at 57600 Baud, 8N1, no hardware or software flow control and it works great. I type in #17 5 and my device responds. When I try to set up my serial port in my C++ code I don't get a response. I know that the software is communicating to the port because an led turns on.
Here is my main:
int main(void)
{
int fd; /* File descriptor for the port */
fd = open("/dev/keyspan1", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
/*
* Could not open the port.
*/
perror("open_port: Unable to open /dev/ttyS0 - ");
}
else
fcntl(fd, F_SETFL, 0);
/*****************************CHANGE PORT OPTIONS***************************/
struct termios options;
/*
* Get the current options for the port...
*/
tcgetattr(fd, &options);
/*
* Set the baud rates to 57600...
*/
cfsetispeed(&options, B57600);
cfsetospeed(&options, B57600);
/*
* Enable the receiver and set local mode...
*/
options.c_cflag |= (CLOCAL | CREAD);
/*
* Set the new options for the port...
*/
tcsetattr(fd, TCSANOW, &options);
/***********************************END PORT OPTIONS***********************/
int n;
n = write(fd, "#17 5 \r", 7);
if (n < 0)
fputs("write() of 8 bytes failed!\n", stderr);
char buff[20];
sleep(1);
n = read(fd, buff, 10);
printf("Returned = %d\n", n);
close(fd);
return(0);
}
Any suggestions would be appreciated. Thanks.
You probably need to initialize your terminal to raw mode. I suggest you use cfmakeraw() to initialize the term options structure. Among others, cfmakeraw will make sure that flow control is disabled, parity checks are disabled, and input is available character by character.
cfmakeraw is non-Posix. If you're concerned with portability, look up the cfmakeraw manpage for the settings it is making.