Для начала научился читать из FLASH Device Identification по команде Read JEDEC ID (9Fh)
CODE
SPI4_CS_LOW;
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 0x9F);
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
data_spi = SPI_I2S_ReceiveData(SPI4); // заглушка, чтобы очистить RXNE
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 0x00);
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
data_flash[0] = SPI_I2S_ReceiveData(SPI4);
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 0x00);
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
data_flash[1] = SPI_I2S_ReceiveData(SPI4);
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 0x00);
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
data_flash[2] = SPI_I2S_ReceiveData(SPI4);
SPI4_CS_HIGH;
Получаю вполне корректный ответ: 0xEF 0x40 0x17. Судя по даташиту такие значения имеют место быть.
Далее я пытался прочитать регистр состояния, после того как выполню команду Write Enable 0x06. По идее бит WEL должен быть установлен, однако читается одни нули 0x00.
Далее прилагаю код:
Инициализация SPI
CODE
void init_SPI()
{
uint8_t x = 0x00;
//настройка CS и включения питания
GPIO_InitTypeDef GPIO_CS;
GPIO_InitTypeDef GPIO_POW;
GPIO_CS.GPIO_Pin = GPIO_Pin_11;
GPIO_CS.GPIO_Mode = GPIO_Mode_OUT;
GPIO_CS.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_CS.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_CS.GPIO_OType = GPIO_OType_PP;
GPIO_POW.GPIO_Pin = GPIO_Pin_11;
GPIO_POW.GPIO_Mode = GPIO_Mode_OUT;
GPIO_POW.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_POW.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_POW.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOE, &GPIO_CS);
GPIO_Init(GPIOB, &GPIO_POW);
SPI_InitTypeDef SPI_struct_itit; //объявляем структуру для инициализации SPI
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI4, ENABLE); // включаем тактирование SPI4
/* Инициализация структуры
Initialize the SPI_Direction - Двухнаправленный SPI или Однонаправленный
Initialize the SPI_Mode member - Slave (ведомый) или Master(Мастер)
Initialize the SPI_DataSize member - бит в сообщении (8 или 16)
Initialize the SPI_CPOL member - задаёт режим работы (режим 0,1,2,3)
Initialize the SPI_CPHA member - задаёт режим работы (режим 0,1,2,3)
Initialize the SPI_NSS member - Управление CS HARD - автоматически, soft - программно
Initialize the SPI_BaudRatePrescaler member - делитель для тактовой частоты SPI
Initialize the SPI_FirstBit member - младший или старшый байт первый
Initialize the SPI_CRCPolynomial member - CRC полином
*/
SPI_struct_itit.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_struct_itit.SPI_Mode = SPI_Mode_Master;
SPI_struct_itit.SPI_DataSize = SPI_DataSize_8b;
SPI_struct_itit.SPI_CPOL = SPI_CPOL_Low;
SPI_struct_itit.SPI_CPHA = SPI_CPHA_1Edge;
SPI_struct_itit.SPI_NSS = SPI_NSS_Soft;
SPI_struct_itit.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
SPI_struct_itit.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_struct_itit.SPI_CRCPolynomial = 7;
SPI_Init (SPI4,&SPI_struct_itit); // инициализируем SPI4
SPI_Cmd(SPI4,ENABLE);
}
{
uint8_t x = 0x00;
//настройка CS и включения питания
GPIO_InitTypeDef GPIO_CS;
GPIO_InitTypeDef GPIO_POW;
GPIO_CS.GPIO_Pin = GPIO_Pin_11;
GPIO_CS.GPIO_Mode = GPIO_Mode_OUT;
GPIO_CS.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_CS.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_CS.GPIO_OType = GPIO_OType_PP;
GPIO_POW.GPIO_Pin = GPIO_Pin_11;
GPIO_POW.GPIO_Mode = GPIO_Mode_OUT;
GPIO_POW.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_POW.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_POW.GPIO_OType = GPIO_OType_PP;
GPIO_Init(GPIOE, &GPIO_CS);
GPIO_Init(GPIOB, &GPIO_POW);
SPI_InitTypeDef SPI_struct_itit; //объявляем структуру для инициализации SPI
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI4, ENABLE); // включаем тактирование SPI4
/* Инициализация структуры
Initialize the SPI_Direction - Двухнаправленный SPI или Однонаправленный
Initialize the SPI_Mode member - Slave (ведомый) или Master(Мастер)
Initialize the SPI_DataSize member - бит в сообщении (8 или 16)
Initialize the SPI_CPOL member - задаёт режим работы (режим 0,1,2,3)
Initialize the SPI_CPHA member - задаёт режим работы (режим 0,1,2,3)
Initialize the SPI_NSS member - Управление CS HARD - автоматически, soft - программно
Initialize the SPI_BaudRatePrescaler member - делитель для тактовой частоты SPI
Initialize the SPI_FirstBit member - младший или старшый байт первый
Initialize the SPI_CRCPolynomial member - CRC полином
*/
SPI_struct_itit.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_struct_itit.SPI_Mode = SPI_Mode_Master;
SPI_struct_itit.SPI_DataSize = SPI_DataSize_8b;
SPI_struct_itit.SPI_CPOL = SPI_CPOL_Low;
SPI_struct_itit.SPI_CPHA = SPI_CPHA_1Edge;
SPI_struct_itit.SPI_NSS = SPI_NSS_Soft;
SPI_struct_itit.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
SPI_struct_itit.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_struct_itit.SPI_CRCPolynomial = 7;
SPI_Init (SPI4,&SPI_struct_itit); // инициализируем SPI4
SPI_Cmd(SPI4,ENABLE);
}
Инициализация GPIO SPI
Код
// инициализация SPI4: SCL,MOSI
Other_GPIO.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_14;
Other_GPIO.GPIO_Mode = GPIO_Mode_AF;
Other_GPIO.GPIO_OType = GPIO_OType_PP;
Other_GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
Other_GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &Other_GPIO);
// инициализация SPI4: MISO
Other_GPIO.GPIO_Pin = GPIO_Pin_13;
Other_GPIO.GPIO_Mode = GPIO_Mode_AF;
Other_GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &Other_GPIO);
// инициализация SPI4: NSS
Other_GPIO.GPIO_Pin = GPIO_Pin_11;
Other_GPIO.GPIO_Mode = GPIO_Mode_OUT;
Other_GPIO.GPIO_OType = GPIO_OType_PP;
Other_GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
Other_GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &Other_GPIO);
//Выбираем альтернативную функцию для всех PIN-SPI
GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_SPI4);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_SPI4);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_SPI4);
Other_GPIO.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_14;
Other_GPIO.GPIO_Mode = GPIO_Mode_AF;
Other_GPIO.GPIO_OType = GPIO_OType_PP;
Other_GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
Other_GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &Other_GPIO);
// инициализация SPI4: MISO
Other_GPIO.GPIO_Pin = GPIO_Pin_13;
Other_GPIO.GPIO_Mode = GPIO_Mode_AF;
Other_GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &Other_GPIO);
// инициализация SPI4: NSS
Other_GPIO.GPIO_Pin = GPIO_Pin_11;
Other_GPIO.GPIO_Mode = GPIO_Mode_OUT;
Other_GPIO.GPIO_OType = GPIO_OType_PP;
Other_GPIO.GPIO_PuPd = GPIO_PuPd_NOPULL;
Other_GPIO.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOE, &Other_GPIO);
//Выбираем альтернативную функцию для всех PIN-SPI
GPIO_PinAFConfig(GPIOE, GPIO_PinSource12, GPIO_AF_SPI4);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_SPI4);
GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_SPI4);
Посылка команды Write Enable
Код
//включение записи во flash
void FLASH_Write_Enable(SPI_TypeDef* SPIx)
{
if (SPIx == SPI4) SPI4_CS_LOW;
else __NOP; // Временная заглушка для SPI1
while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPIx, WriteEnable);
if (SPIx == SPI4) SPI4_CS_HIGH;
else __NOP; // Временная заглушка для SPI1
}
void FLASH_Write_Enable(SPI_TypeDef* SPIx)
{
if (SPIx == SPI4) SPI4_CS_LOW;
else __NOP; // Временная заглушка для SPI1
while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPIx, WriteEnable);
if (SPIx == SPI4) SPI4_CS_HIGH;
else __NOP; // Временная заглушка для SPI1
}
Ну и функция считывания Статус регистра
Код
uint8_t READ_Stat_Reg (SPI_TypeDef* SPIx)
{
volatile uint8_t byte = 0x00;
SPI4_CS_LOW;
while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 0x05);
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
byte = SPI_I2S_ReceiveData(SPI4);
while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 0x00);
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
byte = SPI_I2S_ReceiveData(SPIx);
SPI4_CS_HIGH;
return byte;
}
{
volatile uint8_t byte = 0x00;
SPI4_CS_LOW;
while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 0x05);
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
byte = SPI_I2S_ReceiveData(SPI4);
while(SPI_I2S_GetFlagStatus(SPIx, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(SPI4, 0x00);
while(SPI_I2S_GetFlagStatus(SPI4, SPI_I2S_FLAG_RXNE) == RESET);
byte = SPI_I2S_ReceiveData(SPIx);
SPI4_CS_HIGH;
return byte;
}
основная main()
Код
int main(void)
{
init_CLOCK();
init_GPIO();
GPIOB->ODR &= ~GPIO_Pin_11; //power FLASH on
init_SPI();
FLASH_Write_Enable(SPI4);
x = READ_Stat_Reg(SPI4);
..................
{
init_CLOCK();
init_GPIO();
GPIOB->ODR &= ~GPIO_Pin_11; //power FLASH on
init_SPI();
FLASH_Write_Enable(SPI4);
x = READ_Stat_Reg(SPI4);
..................
брейкпоинт ставлю в функции READ_Stat_Reg на строчке SPI4_CS_HIGH;
Почему читаются одни 0. Наверняка, что то очевидное... Не вижу