I am able to communicate over COM1 fine.
Check your platform_selector.h file in solution directory some pins may be defined differently.
@dweaver The first column below is SPI1 right? Did I put them in the wrong order or something?
//spi
#define STM32F4_SPI_SCLK_PINS {19, 29} // PB3, PB13
#define STM32F4_SPI_MISO_PINS {20, 30} // PB4, PB14
#define STM32F4_SPI_MOSI_PINS {21, 31} // PB5, PB15
//i2c
#define STM32F4_I2C_PORT 1
#define STM32F4_I2C_SCL_PIN 22 // PB6
#define STM32F4_I2C_SDA_PIN 23 // PB7
I don’t know where you got those defined pins. They aren’t from here: netmf-interpreter/platform_selector.h at dev · valoni/netmf-interpreter · GitHub
I have not read the 401 data sheet but if it is compatible with the 411 those pins make to sense?
@dweaver These defined pins are straight out of the G30 datasheet. Valon’s pins are for a different set up
.It looks like your pins are correct. Wow they are totally different than the 411. I assume the pins defined in the image are the same as you used before so I don’t know why you are having the issue?
Sd on this datasheet are for SDIO i mean no for SPI
Spi1 (pb13,pb14,pb15)and spi2(pb3,pb4,pb5) are already defined well on this datasheet
STM32F4xx pins are the same, you can have different combinations is why they may be different.
Port D may not be enabled in my test firmware as it was based on a 48 pin qfn which doesn’t have D
I know Port D is not part of SPI, I have it for a busy pin on the SPI device actually. It has no effect in the success of SPI writes I don’t think…just tells my device if the motor is moving.
I2C pins match the data sheet and get errors as well…
isn’t SPI1 on pins PB3, PB4, and PB5? ?
Can you check one file/folder
Stm32f4_i2c …
It was belong to devices i face i2c problem on .netmf 4.4
I wrote wrong it was ok
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
//
// Copyright (c) Microsoft Corporation. All rights reserved.
// Implementation for STM32F4: Copyright (c) Oberon microsystems, Inc.
//
// *** I2C Driver ***
//
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////
#include <tinyhal.h>
#ifdef STM32F4XX
#include "..\stm32f4xx.h"
#else
#include "..\stm32f2xx.h"
#endif
#if STM32F4_I2C_PORT == 2
#define I2Cx I2C2
#define I2Cx_EV_IRQn I2C2_EV_IRQn
#define I2Cx_ER_IRQn I2C2_ER_IRQn
#define RCC_APB1ENR_I2CxEN RCC_APB1ENR_I2C2EN
#define RCC_APB1RSTR_I2CxRST RCC_APB1RSTR_I2C2RST
#if !defined(STM32F4_I2C_SCL_PIN)
#define STM32F4_I2C_SCL_PIN 26 // PB10
#endif
#if !defined(STM32F4_I2C_SDA_PIN)
#define STM32F4_I2C_SDA_PIN 27 // PB11
#endif
#elif STM32F4_I2C_PORT == 3
#define I2Cx I2C3
#define I2Cx_EV_IRQn I2C3_EV_IRQn
#define I2Cx_ER_IRQn I2C3_ER_IRQn
#define RCC_APB1ENR_I2CxEN RCC_APB1ENR_I2C3EN
#define RCC_APB1RSTR_I2CxRST RCC_APB1RSTR_I2C3RST
#if !defined(STM32F4_I2C_SCL_PIN)
#define STM32F4_I2C_SCL_PIN 8 // PA8
#endif
#if !defined(STM32F4_I2C_SDA_PIN)
#define STM32F4_I2C_SDA_PIN 41 // PC9
#endif
#else // use I2C1 by default
#define I2Cx I2C1
#define I2Cx_EV_IRQn I2C1_EV_IRQn
#define I2Cx_ER_IRQn I2C1_ER_IRQn
#define RCC_APB1ENR_I2CxEN RCC_APB1ENR_I2C1EN
#define RCC_APB1RSTR_I2CxRST RCC_APB1RSTR_I2C1RST
#if !defined(STM32F4_I2C_SCL_PIN)
#define STM32F4_I2C_SCL_PIN 22 // PB6
#endif
#if !defined(STM32F4_I2C_SDA_PIN)
#define STM32F4_I2C_SDA_PIN 23 // PB7
#endif
#endif
static I2C_HAL_XACTION* currentI2CXAction;
static I2C_HAL_XACTION_UNIT* currentI2CUnit;
void STM32F4_I2C_ER_Interrupt (void* param) // Error Interrupt Handler
{
INTERRUPT_START
// pre:
// I2C_SR1_BERR | I2C_SR1_ARLO | I2C_SR1_AF | I2C_SR1_TIMEOUT
I2C_HAL_XACTION* xAction = currentI2CXAction;
I2Cx->SR1 = 0; // reset errors
xAction->Signal(I2C_HAL_XACTION::c_Status_Aborted); // calls XActionStop()
INTERRUPT_END
}
void STM32F4_I2C_EV_Interrupt (void* param) // Event Interrupt Handler
{
INTERRUPT_START
// pre:
// I2C_SR1_SB | I2C_SR1_ADDR | I2C_SR1_BTF | I2C_CR2_ITBUFEN & (I2C_SR1_RXNE | I2C_SR1_TXE)
I2C_HAL_XACTION* xAction = currentI2CXAction;
I2C_HAL_XACTION_UNIT* unit = currentI2CUnit;
int todo = unit->m_bytesToTransfer;
int sr1 = I2Cx->SR1; // read status register
int sr2 = I2Cx->SR2; // clear ADDR bit
int cr1 = I2Cx->CR1; // initial control register
if (unit->IsReadXActionUnit()) { // read transaction
if (sr1 & I2C_SR1_SB) { // start bit
if (todo == 1) {
I2Cx->CR1 = (cr1 &= ~I2C_CR1_ACK); // last byte nack
} else if (todo == 2) {
I2Cx->CR1 = (cr1 |= I2C_CR1_POS); // prepare 2nd byte nack
}
UINT8 addr = xAction->m_address << 1; // address bits
I2Cx->DR = addr + 1; // send header byte with read bit;
} else {
if (sr1 & I2C_SR1_ADDR) { // address sent
if (todo == 1) {
I2Cx->CR1 = (cr1 |= I2C_CR1_STOP); // send stop after single byte
} else if (todo == 2) {
I2Cx->CR1 = (cr1 &= ~I2C_CR1_ACK); // last byte nack
}
} else {
while (sr1 & I2C_SR1_RXNE) { // data available
if (todo == 2) { // 2 bytes remaining
I2Cx->CR1 = (cr1 |= I2C_CR1_STOP); // stop after last byte
} else if (todo == 3) { // 3 bytes remaining
if (!(sr1 & I2C_SR1_BTF)) break; // assure 2 bytes are received
I2Cx->CR1 = (cr1 &= ~I2C_CR1_ACK); // last byte nack
}
UINT8 data = I2Cx->DR; // read data
*(unit->m_dataQueue.Push()) = data; // save data
unit->m_bytesTransferred++;
unit->m_bytesToTransfer = --todo; // update todo
sr1 = I2Cx->SR1; // update status register copy
}
}
if (todo == 1) {
I2Cx->CR2 |= I2C_CR2_ITBUFEN; // enable I2C_SR1_RXNE interrupt
}
}
} else { // write transaction
if (sr1 & I2C_SR1_SB) { // start bit
UINT8 addr = xAction->m_address << 1; // address bits
I2Cx->DR = addr; // send header byte with write bit;
} else {
while (todo && (sr1 & I2C_SR1_TXE)) {
I2Cx->DR = *(unit->m_dataQueue.Pop()); // next data byte;
unit->m_bytesTransferred++;
unit->m_bytesToTransfer = --todo; // update todo
sr1 = I2Cx->SR1; // update status register copy
}
if (!(sr1 & I2C_SR1_BTF)) todo++; // last byte not yet sent
}
}
if (todo == 0) { // all received or all sent
if (!xAction->ProcessingLastUnit()) { // start next unit
I2Cx->CR2 &= ~I2C_CR2_ITBUFEN; // disable I2C_SR1_RXNE interrupt
currentI2CUnit = xAction->m_xActionUnits[ xAction->m_current++ ];
I2Cx->CR1 = I2C_CR1_PE | I2C_CR1_START | I2C_CR1_ACK; // send restart
} else {
xAction->Signal(I2C_HAL_XACTION::c_Status_Completed); // calls XActionStop()
}
}
INTERRUPT_END
}
BOOL I2C_Internal_Initialize()
{
NATIVE_PROFILE_HAL_PROCESSOR_I2C();
if (!(RCC->APB1ENR & RCC_APB1ENR_I2CxEN)) { // only once
currentI2CXAction = NULL;
currentI2CUnit = NULL;
/*
// set pins to AF4 and open drain
if (STM32F4_I2C_PORT == 2 && STM32F4_I2C_SDA_PIN == 25)//PB9
CPU_GPIO_DisablePin(STM32F4_I2C_SDA_PIN, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)0x43); //AF9
else
CPU_GPIO_DisablePin(STM32F4_I2C_SDA_PIN, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)0x43); //AF4
*/
CPU_GPIO_DisablePin( STM32F4_I2C_SDA_PIN, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)0x43 );
CPU_GPIO_DisablePin( STM32F4_I2C_SCL_PIN, RESISTOR_PULLUP, 0, (GPIO_ALT_MODE)0x43 );
RCC->APB1ENR |= RCC_APB1ENR_I2CxEN; // enable I2C clock
RCC->APB1RSTR = RCC_APB1RSTR_I2CxRST; // reset I2C peripheral
RCC->APB1RSTR = 0;
I2Cx->CR2 = SYSTEM_APB1_CLOCK_HZ / 1000000; // APB1 clock in MHz
I2Cx->CCR = (SYSTEM_APB1_CLOCK_HZ / 1000 / 2 - 1) / 100 + 1; // 100KHz
I2Cx->TRISE = SYSTEM_APB1_CLOCK_HZ / (1000 * 1000) + 1; // 1ns;
I2Cx->OAR1 = 0x4000; // init address register
I2Cx->CR1 = I2C_CR1_PE; // enable peripheral
CPU_INTC_ActivateInterrupt(I2Cx_EV_IRQn, STM32F4_I2C_EV_Interrupt, 0);
CPU_INTC_ActivateInterrupt(I2Cx_ER_IRQn, STM32F4_I2C_ER_Interrupt, 0);
}
return TRUE;
}
BOOL I2C_Internal_Uninitialize()
{
NATIVE_PROFILE_HAL_PROCESSOR_I2C();
CPU_INTC_DeactivateInterrupt(I2Cx_EV_IRQn);
CPU_INTC_DeactivateInterrupt(I2Cx_ER_IRQn);
I2Cx->CR1 = 0; // disable peripheral
RCC->APB1ENR &= ~RCC_APB1ENR_I2CxEN; // disable I2C clock
return TRUE;
}
void I2C_Internal_XActionStart( I2C_HAL_XACTION* xAction, bool repeatedStart )
{
NATIVE_PROFILE_HAL_PROCESSOR_I2C();
currentI2CXAction = xAction;
currentI2CUnit = xAction->m_xActionUnits[ xAction->m_current++ ];
UINT32 ccr = xAction->m_clockRate + (xAction->m_clockRate2 << 8);
if (I2Cx->CCR != ccr) { // set clock rate and rise time
UINT32 trise;
if (ccr & I2C_CCR_FS) { // fast => 0.3ns rise time
trise = SYSTEM_APB1_CLOCK_HZ / (1000 * 3333) + 1; // PCLK1 / 3333kHz
} else { // slow => 1.0ns rise time
trise = SYSTEM_APB1_CLOCK_HZ / (1000 * 1000) + 1; // PCLK1 / 1000kHz
}
I2Cx->CR1 = 0; // disable peripheral
I2Cx->CCR = ccr;
I2Cx->TRISE = trise;
}
I2Cx->CR1 = I2C_CR1_PE; // enable and reset special flags
I2Cx->SR1 = 0; // reset error flags
I2Cx->CR2 |= I2C_CR2_ITEVTEN | I2C_CR2_ITERREN; // enable interrupts
I2Cx->CR1 = I2C_CR1_PE | I2C_CR1_START | I2C_CR1_ACK; // send start
}
void I2C_Internal_XActionStop()
{
NATIVE_PROFILE_HAL_PROCESSOR_I2C();
if (I2Cx->SR2 & I2C_SR2_BUSY && !(I2Cx->CR1 & I2C_CR1_STOP)) {
I2Cx->CR1 |= I2C_CR1_STOP; // send stop
}
I2Cx->CR2 &= ~(I2C_CR2_ITBUFEN | I2C_CR2_ITEVTEN | I2C_CR2_ITERREN); // disable interrupts
currentI2CXAction = NULL;
currentI2CUnit = NULL;
}
void I2C_Internal_GetClockRate( UINT32 rateKhz, UINT8& clockRate, UINT8& clockRate2)
{
NATIVE_PROFILE_HAL_PROCESSOR_I2C();
if (rateKhz > 400) rateKhz = 400; // upper limit
UINT32 ccr;
if (rateKhz <= 100) { // slow clock
ccr = (SYSTEM_APB1_CLOCK_HZ / 1000 / 2 - 1) / rateKhz + 1; // round up
if (ccr > 0xFFF) ccr = 0xFFF; // max divider
} else { // fast clock
ccr = (SYSTEM_APB1_CLOCK_HZ / 1000 / 3 - 1) / rateKhz + 1; // round up
ccr |= 0x8000; // set fast mode (duty cycle 1:2)
}
clockRate = (UINT8)ccr; // low byte
clockRate2 = (UINT8)(ccr >> 8); // high byte
}
void I2C_Internal_GetPins(GPIO_PIN& scl, GPIO_PIN& sda)
{
scl = STM32F4_I2C_SCL_PIN;
sda = STM32F4_I2C_SDA_PIN;
}
this is correct file and this part was ok
Could it be something with clock timings? I am at a complete loss. Pins are definitely assigned right…
just keep calm and check
-
firmware if ok
-
drivers if ok
-
check protocols (i2c , spi with simple devices example i2c can be check with SSD3306 it an good option if you get puting on work this oled display that mean i2c was ok etc…)
I have tested Drivers and Protocols on a G30 from GHI, they work great. I am thinking it has to do something with clock timings but am not sure
Thanks Dat, good info for the non volitile memory, but at my age I might have to add it to one note as well
SPI is now working. I had to reduce the clock speed from 5000 kHz to 1000 kHz and change “data valid on rising edge,” from false to true. Somehow that fixed everything…I am not sure why the settings are so much different with this FW.
Still stuck on I2C, 99% sure it is some clock or timing issue in the FW