| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 | 
							- #include "at32f403a_407.h"
 
- #include "spi_flash.h"
 
- #include "spi_common.h"
 
- #include "FreeRTOS.h"
 
- #include "task.h"
 
- #include "common_config.h"
 
- #include <string.h>
 
- #include <stdio.h>
 
- #define SPI_FLASH			SPI3
 
- #define INCLUDE_SPI_TEST	0
 
- #define CMD_WREN	0x06 // +
 
- #define CMD_WRDI	0x04 // +
 
- #define CMD_WRSR	0x01 // +
 
- #define CMD_RDSR	0x05 // +
 
- #define CMD_READ	0x03 // +
 
- #define CMD_SE		0x20 // + Block Erse 4 Kbytes 
 
- #define CMD_BE		0x52 // Block Erase 32 Kbytes 
 
- #define CMD_CE		0x60 // + Chip Erase
 
- #define CMD_PP		0x02 // + Byte/Page Program (1 to 256 Bytes)
 
- #define CMD_RDSFDP	0x5A // - not used for FLASH_TYPE_AT25SF161
 
- #define SR_WIP	(1 << 0)
 
- #define SR_WEL	(1 << 1)
 
- #define SR_SRWD	(1 << 7)
 
- spi_flash_desc_t spi_flash_desc;
 
- //
 
- static uint8_t spi_tx_rx(uint8_t byte) 
 
- {
 
-     return common_spi_tx_rx(SPI_FLASH, byte);
 
- }
 
- //
 
- static inline void wait_write_enable(void) 
 
- {
 
- 	uint8_t status;
 
-     
 
- 	SPI_FLASH_CS_L();
 
- 	spi_tx_rx(CMD_RDSR);
 
- 	
 
-     do {
 
- 		status = spi_tx_rx(0);
 
- 	} while (!(status & SR_WEL));
 
-     
 
- 	SPI_FLASH_CS_H();
 
- }
 
- //
 
- static inline void wait_write_end(void) 
 
- {
 
- 	uint8_t status;
 
-     
 
- 	SPI_FLASH_CS_L();
 
- 	spi_tx_rx(CMD_RDSR);
 
- 	
 
-     do {
 
- 		status = spi_tx_rx(0);
 
- 	} while (status & SR_WIP);
 
- 	
 
-     SPI_FLASH_CS_H();
 
- }
 
- //
 
- static inline void send_addr(int addr) 
 
- {
 
- 	spi_tx_rx((addr >> 16) & 0xFF);
 
- 	spi_tx_rx((addr >> 8) & 0xFF);
 
- 	spi_tx_rx(addr & 0xFF);
 
- }
 
- //
 
- static int spi_flash_read_sfdp(int addr, void *buf, size_t len) 
 
- {
 
-     uint8_t *ptr = (uint8_t*)buf;
 
- 	SPI_FLASH_CS_L();
 
- 	spi_tx_rx(CMD_RDSFDP);
 
- 	send_addr(addr);
 
- 	spi_tx_rx(0);
 
- 	while (len--)
 
-         *ptr++ = spi_tx_rx(0);
 
- 	SPI_FLASH_CS_H();
 
- 	return 0;
 
- }
 
- //
 
- ssize_t spi_flash_read(int addr, void *buf, size_t len, uint32_t timeout) 
 
- {
 
-     uint8_t *ptr = (uint8_t*)buf;
 
- 	(void)timeout;
 
- 	
 
- 	SPI_FLASH_CS_L();
 
- 	spi_tx_rx(CMD_READ);
 
- 	send_addr(addr);
 
- 	while (len--)
 
-         *ptr++ = spi_tx_rx(0);
 
- 	SPI_FLASH_CS_H();
 
- 	return len;
 
- }
 
- #define TIMEOUT 10000
 
- uint16_t spi_flash_pp(int addr, const void *buf, size_t len, uint32_t timeout) 
 
- {
 
-     uint8_t *ptr = (uint8_t*)buf;
 
- 	(void)timeout;
 
- 	ssize_t ret = 0;
 
- 	if ((addr & 0xFF) + len > 0xFF)
 
- 	    len = 0x100 - (addr & 0xFF);
 
- 	ret = len;
 
- 	SPI_FLASH_CS_L();
 
- 	spi_tx_rx(CMD_WREN);
 
- 	SPI_FLASH_CS_H();
 
- 	wait_write_enable();
 
- 	SPI_FLASH_CS_L();
 
- 	spi_tx_rx(CMD_PP);
 
- 	send_addr(addr);
 
- 	while (len--)
 
-         spi_tx_rx(*ptr++);
 
- 	SPI_FLASH_CS_H();
 
- 	wait_write_end();
 
- 	return ret;
 
- }
 
- //
 
- ssize_t spi_flash_write(int addr, const void *buf, size_t len, uint32_t timeout) 
 
- {
 
- 	(void)timeout;
 
- 	int ret = 0, offset = 0;
 
- 	do {
 
-         ret = spi_flash_pp(addr + offset, (uint8_t*)buf + offset, len - offset, 0);
 
- 	    offset += ret;
 
- 	} while (len - offset);
 
- 	return 0;
 
- }
 
- //
 
- int spi_flash_chip_erase(uint32_t timeout) 
 
- {
 
- 	(void)timeout;
 
- 	SPI_FLASH_CS_L();
 
- 	spi_tx_rx(CMD_WREN);
 
- 	SPI_FLASH_CS_H();
 
- 	wait_write_enable();
 
- 	SPI_FLASH_CS_L();
 
- 	spi_tx_rx(CMD_CE);
 
- 	SPI_FLASH_CS_H();
 
- 	wait_write_end();
 
- 	return 0;
 
- }
 
- //
 
- int spi_flash_erase_sector(int addr, uint32_t timeout) 
 
- {
 
- 	(void)timeout;
 
- 	SPI_FLASH_CS_L();
 
- 	spi_tx_rx(CMD_WREN);
 
- 	SPI_FLASH_CS_H();
 
- 	wait_write_enable();
 
- 	SPI_FLASH_CS_L();
 
- 	spi_tx_rx(CMD_SE);
 
- 	send_addr(addr);
 
- 	SPI_FLASH_CS_H();
 
- 	wait_write_end();
 
- 	return 0;
 
- }
 
- //
 
- unsigned int spi_flash_get_sector_size(void) {
 
- 	return spi_flash_desc.sector_size;
 
- }
 
- //
 
- unsigned int spi_flash_get_sector_count(void) {
 
- 	return spi_flash_desc.sector_count;
 
- }
 
- //
 
- unsigned int spi_flash_get_total_size(void) {
 
- 	return spi_flash_desc.sector_count * spi_flash_desc.sector_size;
 
- }
 
- //
 
- bool spi_flash_is_init(void) {
 
- 	return spi_flash_desc.present;
 
- }
 
- //
 
- bool spi_flash_init(void) 
 
- {
 
-     spi_flash_desc.sector_size = SPI_FLASH_SECTOR_SIZE;
 
-     spi_flash_desc.sector_erase_op = 32;
 
-     spi_flash_desc.sector_count = 512;
 
-     spi_flash_desc.present = true;
 
-     
 
-     return true;
 
- }
 
- // -------------------------------------------------------------------------- //
 
- #if INCLUDE_SPI_TEST
 
- const uint8_t txbuf1[] = "This film came out on DVD yesterday and I rushed to buy it. \
 
- 		    This version is the first to render all the detail and perfection \
 
- 		    of Jack Cardiff's amazing compositions and brilliant, varied photography. \
 
- 		    As a collection of memorable images, this film is better than any comparable \
 
- 		    historical epic of the period and even gives GWTW a run for its money. \
 
- 		    King Vidor's direction is a series of 'tableaux vivants' where the \
 
- 		    characters are not posing but acting in a very natural, period-specific way. \
 
- 		    I have never had a problem with this adaptation of Tolstoy's novel. \
 
- 		    I think it is a wonderful introduction to the period and the novel and that \
 
- 		    it is a very poetic, very original work in its own right. Henry Fonda's \
 
- 		    characterization is especially moving, including great memorable interactions \
 
- 		    with/reations to Mel Ferrer, Audrey Hepburn, Helmut Dantine and John Mills, but \
 
- 		    all members of the cast are actually perfect. The harrowing last 45 minutes of \
 
- 		    the film manage to convey a sense of history, a sense of grandeur as well as to \
 
- 		    communicate very clearly Tolstoy's ideas about the meaning of life, by relying \
 
- 		    mostly on the power of memorable images. The most conspicuous handicap of this movie, \
 
- 		    in my opinion, is its soundtrack (in glorious mono). The barely hi-fi recording of \
 
- 		    dialogues and music sounds pinched, hollow and tinny and it always has in very version \
 
- 		    I have ever seen: in the theatres, on TV and on video. Even the soundtrack album is \
 
- 		    an atrocity. In some scenes, before the necessary adjustments of bass and treble, \
 
- 		    Audrey Hepburn's and Mel Ferrer's voices actually hurt your ear. Nino Rota's very \
 
- 		    Russian-sounding score is serviceable and melodic, although rather sparse in its \
 
- 		    orchestration and in the number of players. One can only wonder what 'War and Peace' \
 
- 		    could have sounded like with a cohort of Hollywood arrangers, decent recording facilities \
 
- 		    and lavish, varied orchestrations in true high fidelity and stereophonic sound. \
 
- 		    According to Lukas Kendall of 'Film Score Monthly', the original recording elements \
 
- 		    of the soundtrack have long ago disappeared, which is the common lot of international, \
 
- 		    independent co-productions of the era. Someone somewhere is certainly guilty of \
 
- 		    skimping on quality or embezzlement for this 1956 movie to sound so much worse \
 
- 		    than a 1939, pre-hi-fi epic like GWTW. Like all VistaVision films, this one was \
 
- 		    meant to be shown in Perspecta Stereophonic Sound where the mono dialog track was \
 
- 		    meant to be channelled to three different directions, making it directional, while \
 
- 		    the separate mono music + sound effects track was generally directed to all three \
 
- 		    speakers at the same time. The results fooled the viewers into thinking everything \
 
- 		    was in true stereo and the reproduction of the music was usually in very high fidelity. \
 
- 		    Maybe the soundtrack used on the DVD is a mono reduction of those two separate tracks \
 
- 		    that has squandered that fidelity and maybe the DVD can be issued again with better \
 
- 		    results in some kind of 4.0 presentation. When they do, very little electronic \
 
- 		    restoration work will be needed to make the image absolutely perfect. \
 
- 		    But let's concentrate on the positive: This film is a summit of visual \
 
- 		    splendour and its sets, costumes, colour photography, composition and lighting \
 
-             achieve, in every single scene, wonders of artistry, creativity and delicacy \
 
- 		    But let's concentrate on the positive: This film is a summit of visual \
 
- 		    splendour and its sets, costumes, colour photography, composition and lighting \
 
- 		    achieve, in every single scene, wonders of artistry, creativity and delicacy \
 
- 		    that will probably never be equalled. Suffice it to say that it has, \
 
- 		    among many other treasures, a sunrise duel scene in the snow that still has viewers \
 
- 		    wondering whether it was shot outdoors or in a studio and that will have them wondering foreverhsgkhgkshgu.\r\n";
 
- #define countof(a) (sizeof(a) / sizeof(*(a)))
 
- #define  bufsize1 (countof(txbuf1)-1)
 
- uint8_t  rxbuf1[bufsize1] = {0};
 
- bool spi_flash_test(void) {
 
-     if (!spi_flash_is_init()) {
 
- 		return false;
 
-     }
 
- 	
 
- 	const unsigned int sector_count = spi_flash_get_sector_count();
 
- 	const unsigned int sector_size = spi_flash_get_sector_size();
 
- 	const unsigned int total_size = spi_flash_get_total_size();
 
- 	printf("Present: %u sectors, %u bytes per sector (%u bytes total)\r\n",
 
-             sector_count, sector_size, total_size);
 
-     for (uint16_t i = 0; i < sector_count; i++) {
 
- 		printf("sector: %u/%u ", i, sector_count);
 
- 		spi_flash_erase_sector(i * sector_size, 0);
 
- 		spi_flash_write(i * sector_size, txbuf1, bufsize1, 0);
 
- 		memset(rxbuf1, 0, bufsize1);
 
- 		spi_flash_read(i * sector_size, rxbuf1, bufsize1, 0);
 
- 		if (memcmp(txbuf1, rxbuf1, bufsize1) != 0) {
 
- 			printf("fail\r\n");
 
- 			return false;
 
- 		}
 
- 		printf("ok\r\n");
 
-     }
 
- 	printf("\r\nDone\r\n");	
 
-     return true;
 
- }
 
- #endif
 
 
  |