AP mode

Dependencies:   NetworkSocketAPI WizFi310Interface mbed

Fork of WizFi310_TCP_Echo_Server_Example by WIZnet

Committer:
maru536
Date:
Tue Oct 03 05:38:58 2017 +0000
Revision:
8:e26236864101
Parent:
2:8d119e9b8f5a
comp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
maru536 2:8d119e9b8f5a 1 /**
maru536 2:8d119e9b8f5a 2 * ==================================================== Dec 21 2013, kayeks ==
maru536 2:8d119e9b8f5a 3 * VS1053.cpp
maru536 2:8d119e9b8f5a 4 * ===========================================================================
maru536 2:8d119e9b8f5a 5 * Just a simple library for VLSI's mp3/midi codec chip
maru536 2:8d119e9b8f5a 6 * - Minimal and simple implementation (and dirty too)
maru536 2:8d119e9b8f5a 7 *
maru536 2:8d119e9b8f5a 8 * Modified on 05 September 2015 by Vassilis Serasidis.
maru536 2:8d119e9b8f5a 9 * - Added a patch for playing MP3 files on some "LC Technology" VS1053 boards.
maru536 2:8d119e9b8f5a 10 *
maru536 2:8d119e9b8f5a 11 *
maru536 2:8d119e9b8f5a 12 */
maru536 2:8d119e9b8f5a 13
maru536 2:8d119e9b8f5a 14 #include "mbed.h"
maru536 2:8d119e9b8f5a 15 #include "VS1053.h"
maru536 2:8d119e9b8f5a 16
maru536 2:8d119e9b8f5a 17 /** Constructor of class VS1053. */
maru536 2:8d119e9b8f5a 18 VS1053::VS1053(PinName mosiPin, PinName misoPin, PinName sckPin,
maru536 2:8d119e9b8f5a 19 PinName csPin, PinName bsyncPin, PinName dreqPin,
maru536 2:8d119e9b8f5a 20 PinName rstPin, uint32_t spiFrequency)
maru536 2:8d119e9b8f5a 21 :
maru536 2:8d119e9b8f5a 22 spi(mosiPin, misoPin, sckPin),
maru536 2:8d119e9b8f5a 23 cs(csPin),
maru536 2:8d119e9b8f5a 24 bsync(bsyncPin), //dcs pin
maru536 2:8d119e9b8f5a 25 dreq(dreqPin),
maru536 2:8d119e9b8f5a 26 rst(rstPin)
maru536 2:8d119e9b8f5a 27 {
maru536 2:8d119e9b8f5a 28 //spi.format(8, 0);
maru536 2:8d119e9b8f5a 29 //spi.frequency(spiFrequency);
maru536 2:8d119e9b8f5a 30
maru536 2:8d119e9b8f5a 31 // Initialize outputs
maru536 2:8d119e9b8f5a 32 cs = 1;
maru536 2:8d119e9b8f5a 33 bsync = 1;
maru536 2:8d119e9b8f5a 34 rst = 1;
maru536 2:8d119e9b8f5a 35 }
maru536 2:8d119e9b8f5a 36
maru536 2:8d119e9b8f5a 37 /** Destructor of class VS1053. */
maru536 2:8d119e9b8f5a 38 VS1053::~VS1053() {
maru536 2:8d119e9b8f5a 39 }
maru536 2:8d119e9b8f5a 40
maru536 2:8d119e9b8f5a 41 /** Make a hardware reset by hitting VS1053's RESET pin. */
maru536 2:8d119e9b8f5a 42 void VS1053::hardwareReset() {
maru536 2:8d119e9b8f5a 43 rst = 0;
maru536 2:8d119e9b8f5a 44 wait(.05);
maru536 2:8d119e9b8f5a 45 rst = 1;
maru536 2:8d119e9b8f5a 46 wait(.05);
maru536 2:8d119e9b8f5a 47 }
maru536 2:8d119e9b8f5a 48
maru536 2:8d119e9b8f5a 49 /** Patch for some LC Technology VS1053 board with "no sound" problem.
maru536 2:8d119e9b8f5a 50 * 5 September 2015 bby Vassilis Serasidis
maru536 2:8d119e9b8f5a 51 */
maru536 2:8d119e9b8f5a 52 void VS1053::modeSwitch(void)
maru536 2:8d119e9b8f5a 53 {
maru536 2:8d119e9b8f5a 54 //GPIO_DDR
maru536 2:8d119e9b8f5a 55 writeReg(SCI_WRAMADDR, 0xc017);
maru536 2:8d119e9b8f5a 56 writeReg(SCI_WRAM, 0x0003);
maru536 2:8d119e9b8f5a 57
maru536 2:8d119e9b8f5a 58 wait(.05);
maru536 2:8d119e9b8f5a 59 writeReg(SCI_MODE, (1<<SM_SDINEW) | (1<<SM_RESET));
maru536 2:8d119e9b8f5a 60 wait(.05);
maru536 2:8d119e9b8f5a 61 }
maru536 2:8d119e9b8f5a 62
maru536 2:8d119e9b8f5a 63 /** Send a data byte to VS1053. */
maru536 2:8d119e9b8f5a 64 void VS1053::sendDataByte(uint8_t data) {
maru536 2:8d119e9b8f5a 65 while (!dreq);
maru536 2:8d119e9b8f5a 66 bsync = 0;
maru536 2:8d119e9b8f5a 67 spi.write(data);
maru536 2:8d119e9b8f5a 68 bsync = 1;
maru536 2:8d119e9b8f5a 69 }
maru536 2:8d119e9b8f5a 70
maru536 2:8d119e9b8f5a 71 /** Send a data block specified as a pointer to VS1053.
maru536 2:8d119e9b8f5a 72 * @return Data length successfully sent.
maru536 2:8d119e9b8f5a 73 */
maru536 2:8d119e9b8f5a 74 size_t VS1053::sendDataBlock(unsigned char* data, size_t length) {
maru536 2:8d119e9b8f5a 75 size_t n, sizeSent = 0;
maru536 2:8d119e9b8f5a 76
maru536 2:8d119e9b8f5a 77 if (!data || !length) return 0;
maru536 2:8d119e9b8f5a 78 while (length) {
maru536 2:8d119e9b8f5a 79 n = length < 32 ? length : 32;
maru536 2:8d119e9b8f5a 80 while (!dreq);
maru536 2:8d119e9b8f5a 81 bsync = 0;
maru536 2:8d119e9b8f5a 82 for (uint32_t i = 0; i < n; i++) {
maru536 2:8d119e9b8f5a 83 spi.write(*data++);
maru536 2:8d119e9b8f5a 84 sizeSent++; length--;
maru536 2:8d119e9b8f5a 85 }
maru536 2:8d119e9b8f5a 86 bsync = 1;
maru536 2:8d119e9b8f5a 87 }
maru536 2:8d119e9b8f5a 88 return sizeSent;
maru536 2:8d119e9b8f5a 89 }
maru536 2:8d119e9b8f5a 90
maru536 2:8d119e9b8f5a 91 size_t VS1053::sendDataBlock(TCPSocket* socket, int content_length) {
maru536 2:8d119e9b8f5a 92 size_t n, sizeSent = 0;
maru536 2:8d119e9b8f5a 93 unsigned char c;
maru536 2:8d119e9b8f5a 94 while (socket->recv(&c, sizeof(c)) >= 0 && sizeSent < content_length) {
maru536 2:8d119e9b8f5a 95 while (!dreq);
maru536 2:8d119e9b8f5a 96 bsync = 0;
maru536 2:8d119e9b8f5a 97 spi.write(c);
maru536 2:8d119e9b8f5a 98 sizeSent++;
maru536 2:8d119e9b8f5a 99 bsync = 1;
maru536 2:8d119e9b8f5a 100 }
maru536 2:8d119e9b8f5a 101 printf("\nplay size: %d\n", sizeSent);
maru536 2:8d119e9b8f5a 102 return sizeSent;
maru536 2:8d119e9b8f5a 103 }
maru536 2:8d119e9b8f5a 104
maru536 2:8d119e9b8f5a 105 /** Change VS1053's PLL setting for speedup. */
maru536 2:8d119e9b8f5a 106 void VS1053::clockUp() {
maru536 2:8d119e9b8f5a 107 // Set CLKI to 43.0-55.3 MHz
maru536 2:8d119e9b8f5a 108 writeReg(SCI_CLOCKF, 0x8800); // SC_MULT=4 (3.5x), SC_ADD=1 (+1.0x)
maru536 2:8d119e9b8f5a 109 wait(0.01);
maru536 2:8d119e9b8f5a 110 }
maru536 2:8d119e9b8f5a 111
maru536 2:8d119e9b8f5a 112 /** Send cancel request to VS1053.
maru536 2:8d119e9b8f5a 113 * @return Zero at failure, non-zero at success.
maru536 2:8d119e9b8f5a 114 */
maru536 2:8d119e9b8f5a 115 bool VS1053::sendCancel() {
maru536 2:8d119e9b8f5a 116 uint16_t reg;
maru536 2:8d119e9b8f5a 117
maru536 2:8d119e9b8f5a 118 // Set SM_CANCEL bit
maru536 2:8d119e9b8f5a 119 reg = readReg(SCI_MODE);
maru536 2:8d119e9b8f5a 120 if (reg & 0x0008) {
maru536 2:8d119e9b8f5a 121 // Abort if SM_CANCEL is still set
maru536 2:8d119e9b8f5a 122 return false;
maru536 2:8d119e9b8f5a 123 }
maru536 2:8d119e9b8f5a 124 writeReg(SCI_MODE, reg | 0x0008);
maru536 2:8d119e9b8f5a 125 return true;
maru536 2:8d119e9b8f5a 126 }
maru536 2:8d119e9b8f5a 127
maru536 2:8d119e9b8f5a 128 /** Attempt a termination of playing.
maru536 2:8d119e9b8f5a 129 * Please call this repeatedly during data stream tramsission until it successes.
maru536 2:8d119e9b8f5a 130 * @return Zero at failure, non-zero at success.
maru536 2:8d119e9b8f5a 131 */
maru536 2:8d119e9b8f5a 132 bool VS1053::stop() {
maru536 2:8d119e9b8f5a 133 uint16_t reg;
maru536 2:8d119e9b8f5a 134 uint8_t endFillByte;
maru536 2:8d119e9b8f5a 135 size_t n, length;
maru536 2:8d119e9b8f5a 136
maru536 2:8d119e9b8f5a 137 // If SM_CANCEL is still set, do nothing
maru536 2:8d119e9b8f5a 138 reg = readReg(SCI_MODE);
maru536 2:8d119e9b8f5a 139 if (reg & 0x0008) {
maru536 2:8d119e9b8f5a 140 return false;
maru536 2:8d119e9b8f5a 141 }
maru536 2:8d119e9b8f5a 142
maru536 2:8d119e9b8f5a 143 // Read endFillByte from XRAM <1E06h>
maru536 2:8d119e9b8f5a 144 writeReg(SCI_WRAMADDR, 0x1e06);
maru536 2:8d119e9b8f5a 145 reg = readReg(SCI_WRAM);
maru536 2:8d119e9b8f5a 146
maru536 2:8d119e9b8f5a 147 // Send lower 8 bits of endFillByte 2,052 times
maru536 2:8d119e9b8f5a 148 endFillByte = reg & 0xff;
maru536 2:8d119e9b8f5a 149 length = 2052;
maru536 2:8d119e9b8f5a 150 while (length) {
maru536 2:8d119e9b8f5a 151 n = length < 32 ? length : 32;
maru536 2:8d119e9b8f5a 152 while (!dreq);
maru536 2:8d119e9b8f5a 153 bsync = 0;
maru536 2:8d119e9b8f5a 154 for (uint32_t i = 0; i < n; i++) {
maru536 2:8d119e9b8f5a 155 spi.write(endFillByte);
maru536 2:8d119e9b8f5a 156 length--;
maru536 2:8d119e9b8f5a 157 }
maru536 2:8d119e9b8f5a 158 bsync = 1;
maru536 2:8d119e9b8f5a 159 }
maru536 2:8d119e9b8f5a 160 // Check if both HDAT0 and HDAT1 are cleared
maru536 2:8d119e9b8f5a 161 return readReg(SCI_HDAT0) == 0x0000 && readReg(SCI_HDAT1) == 0x0000;
maru536 2:8d119e9b8f5a 162 }
maru536 2:8d119e9b8f5a 163
maru536 2:8d119e9b8f5a 164 /**
maru536 2:8d119e9b8f5a 165 * Set the VS1053 volume.
maru536 2:8d119e9b8f5a 166 *
maru536 2:8d119e9b8f5a 167 */
maru536 2:8d119e9b8f5a 168 void VS1053::setVolume(uint8_t vol)
maru536 2:8d119e9b8f5a 169 {
maru536 2:8d119e9b8f5a 170 uint16_t value = vol;
maru536 2:8d119e9b8f5a 171 value <<= 8;
maru536 2:8d119e9b8f5a 172 value |= vol;
maru536 2:8d119e9b8f5a 173
maru536 2:8d119e9b8f5a 174 writeReg(SCI_VOL,value); // VOL
maru536 2:8d119e9b8f5a 175 }
maru536 2:8d119e9b8f5a 176
maru536 2:8d119e9b8f5a 177 /** Write to an SCI (Serial Control Interface) register entry. */
maru536 2:8d119e9b8f5a 178 void VS1053::writeReg(uint8_t addr, uint16_t word) {
maru536 2:8d119e9b8f5a 179 // If addr is out-of-range, do nothing
maru536 2:8d119e9b8f5a 180 if (addr > 0x0f) {
maru536 2:8d119e9b8f5a 181 return;
maru536 2:8d119e9b8f5a 182 }
maru536 2:8d119e9b8f5a 183
maru536 2:8d119e9b8f5a 184 while (!dreq);
maru536 2:8d119e9b8f5a 185 cs = 0;
maru536 2:8d119e9b8f5a 186 spi.write(0x02); // Send a "Write SCI" instruction (02h),
maru536 2:8d119e9b8f5a 187 spi.write(addr); // target address,
maru536 2:8d119e9b8f5a 188 spi.write(word >> 8); // high byte,
maru536 2:8d119e9b8f5a 189 spi.write(word & 0xff); // then low byte
maru536 2:8d119e9b8f5a 190 while (!dreq);
maru536 2:8d119e9b8f5a 191 cs = 1;
maru536 2:8d119e9b8f5a 192 }
maru536 2:8d119e9b8f5a 193
maru536 2:8d119e9b8f5a 194 /** Read an SCI (Serial Control Interface) register entry.
maru536 2:8d119e9b8f5a 195 * @return Register value or 0000h when invalid address was specified.
maru536 2:8d119e9b8f5a 196 */
maru536 2:8d119e9b8f5a 197 uint16_t VS1053::readReg(uint8_t addr) {
maru536 2:8d119e9b8f5a 198 uint16_t word;
maru536 2:8d119e9b8f5a 199
maru536 2:8d119e9b8f5a 200 // If addr is out-of-range, return 0000h
maru536 2:8d119e9b8f5a 201 if (addr > 0x0f) {
maru536 2:8d119e9b8f5a 202 return 0x0000;
maru536 2:8d119e9b8f5a 203 }
maru536 2:8d119e9b8f5a 204
maru536 2:8d119e9b8f5a 205 while (!dreq);
maru536 2:8d119e9b8f5a 206 cs = 0;
maru536 2:8d119e9b8f5a 207 spi.write(0x03); // Send a "Read SCI" instruction (03h)
maru536 2:8d119e9b8f5a 208 spi.write(addr); // and target address
maru536 2:8d119e9b8f5a 209 word = spi.write(0xff) << 8; // Receive high byte with dummy data FFh
maru536 2:8d119e9b8f5a 210 word |= spi.write(0xff); // Receive low byte
maru536 2:8d119e9b8f5a 211 while (!dreq);
maru536 2:8d119e9b8f5a 212 cs = 1;
maru536 2:8d119e9b8f5a 213 return word;
maru536 2:8d119e9b8f5a 214 }