Skip to content

Commit f56f198

Browse files
committed
add firmware
1 parent f90364f commit f56f198

File tree

4 files changed

+192
-0
lines changed

4 files changed

+192
-0
lines changed

README.md

+192
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,194 @@ void Audio_SelectStation(uint16_t new_stationID) {
198198
}
199199
```
200200

201+
### OLED底层驱动
202+
203+
OLED底层驱动还是使用了我的[祖传代码](https://github.com/kaidegit/HWDrivers4MCU/tree/main/OLED_SSD1306_i2c),虽然是i2c的,但是稍微改改发送接口,从spi发送就可以正常使用了。
204+
205+
```c++
206+
void MY_SPI_Init() {
207+
spi_bus_config_t buscfg = {
208+
.miso_io_num=-1,
209+
.mosi_io_num=OLED_MOSI_Pin,
210+
.sclk_io_num=OLED_CLK_Pin,
211+
.quadwp_io_num=-1,
212+
.quadhd_io_num=-1,
213+
.max_transfer_sz=0
214+
};
215+
spi_device_interface_config_t devcfg = {
216+
.clock_speed_hz=1 * 1000 * 1000, //Clock out at 1 MHz
217+
.mode=0, //SPI mode 0
218+
.spics_io_num=-1, //CS pin
219+
.queue_size=7, //We want to be able to queue 7 transactions at a time
220+
};
221+
ESP_ERROR_CHECK(spi_bus_initialize(OLED_SPI_HOST, &buscfg, SPI_DMA_DISABLED));
222+
ESP_ERROR_CHECK(spi_bus_add_device(OLED_SPI_HOST, &devcfg, &oled_spi_handle));
223+
}
224+
225+
spi_device_handle_t oled_spi_handle;
226+
227+
void oled_send(uint8_t dc, uint8_t data) {
228+
spi_transaction_t t = {0};
229+
t.length = 8;
230+
t.tx_buffer = &data;
231+
gpio_set_level(OLED_DC_Pin, dc == 0x40);
232+
spi_device_polling_transmit(oled_spi_handle, &t);
233+
}
234+
```
235+
236+
### FM底层驱动
237+
238+
这款FM芯片有个坑,它并非像传统的i2c设备一样,可以通过发送设备地址-发送寄存器地址-读或者写值这种操作方法来操作,而是只能顺序读取或者写入所有寄存器数据,具体可以参考数据手册。
239+
240+
由于没能找到比较好的驱动,我这里参考github上一个适配于arduino的程序自己写了一个较为简陋的驱动
241+
242+
```c++
243+
struct RDA_Handler RDA5807;
244+
245+
RADIO_FREQ FMStationList[50] = {0};
246+
uint16_t FMStationNum = 0;
247+
248+
void RDA_ReadAllInfo() {
249+
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
250+
i2c_master_start(cmd);
251+
i2c_master_write_byte(cmd, 0x21, 1);
252+
// from 0x0A high to 0x0C low
253+
uint8_t i2c_data_array[6];
254+
// read 0x0A
255+
i2c_master_read_byte(cmd, i2c_data_array + 0, 0);
256+
i2c_master_read_byte(cmd, i2c_data_array + 1, 0);
257+
// read 0x0B
258+
i2c_master_read_byte(cmd, i2c_data_array + 2, 0);
259+
i2c_master_read_byte(cmd, i2c_data_array + 3, 0);
260+
// read 0x0C
261+
i2c_master_read_byte(cmd, i2c_data_array + 4, 0);
262+
i2c_master_read_byte(cmd, i2c_data_array + 5, 1);
263+
i2c_master_stop(cmd);
264+
i2c_master_cmd_begin(FM_I2C_HOST, cmd, 1000 / portTICK_RATE_MS);
265+
i2c_cmd_link_delete(cmd);
266+
RDA5807.radioInfo.rds = i2c_data_array[0] & 0x80;
267+
uint16_t readChan = ((i2c_data_array[0] & 0x03) << 8) + i2c_data_array[1];
268+
switch (RDA5807.band) {
269+
case RADIO_BAND_US:
270+
RDA5807.freq = RDA5807.channelSpacing * readChan + 87 * 1000;
271+
break;
272+
case RADIO_BAND_JP:
273+
case RADIO_BAND_WW:
274+
RDA5807.freq = RDA5807.channelSpacing * readChan + 76 * 1000;
275+
break;
276+
case RADIO_BAND_EE:
277+
RDA5807.freq = RDA5807.channelSpacing * readChan + 65 * 1000;
278+
}
279+
RDA5807.radioInfo.rssi = i2c_data_array[2] >> 2;
280+
}
281+
282+
void RDA_WriteAllInfo() {
283+
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
284+
i2c_master_start(cmd);
285+
i2c_master_write_byte(cmd, 0x20, 1);
286+
for (uint8_t i = 2; i < 8; i++) {
287+
i2c_master_write_byte(cmd, RDA5807.regList[i] >> 8, 1);
288+
i2c_master_write_byte(cmd, RDA5807.regList[i] & 0xff, 1);
289+
}
290+
i2c_master_stop(cmd);
291+
i2c_master_cmd_begin(FM_I2C_HOST, cmd, 1000 / portTICK_RATE_MS);
292+
i2c_cmd_link_delete(cmd);
293+
}
294+
295+
void RDA_Init() {
296+
RDA5807.channelSpacing = 100;
297+
// Reg 0x00 and 0x01 are not used
298+
RDA5807.regList[0] = 0;
299+
RDA5807.regList[1] = 0;
300+
RDA5807.regList[2] = 0b11000000 << 8 | 0b00000011;
301+
RDA5807.regList[3] = 0b00000000 << 8 | 0b00000000;
302+
RDA5807.regList[4] = 0b00001000 << 8 | 0b00000000;
303+
RDA5807.regList[5] = 0b10000100 << 8 | 0b11010100;
304+
RDA5807.regList[6] = 0b00000000 << 8 | 0b00000000;
305+
RDA5807.regList[7] = 0b00000000 << 8 | 0b00000000;
306+
307+
RDA_WriteAllInfo();
308+
RDA_Reset();
309+
}
310+
311+
void RDA_Reset() {
312+
RDA5807.regList[RADIO_REG_CTRL] |= RADIO_REG_CTRL_RESET;
313+
RDA_WriteAllInfo();
314+
vTaskDelay(100 / portTICK_RATE_MS);
315+
RDA5807.regList[RADIO_REG_CTRL] &= !RADIO_REG_CTRL_RESET;
316+
RDA_WriteAllInfo();
317+
}
318+
319+
void RDA_SetBandFrequency(enum RADIO_BAND newBand, RADIO_FREQ newFreq) {
320+
RDA_SetBand(newBand);
321+
RDA_SetFrequency(newFreq);
322+
}
323+
324+
void RDA_SetFrequency(RADIO_FREQ newFreq) {
325+
RADIO_FREQ freqHigh, freqLow;
326+
switch (RDA5807.band) {
327+
case RADIO_BAND_US:
328+
freqLow = 87000;
329+
freqHigh = 108000;
330+
break;
331+
case RADIO_BAND_JP:
332+
freqLow = 76000;
333+
freqHigh = 91000;
334+
break;
335+
case RADIO_BAND_WW:
336+
freqLow = 76000;
337+
freqHigh = 108000;
338+
break;
339+
case RADIO_BAND_EE:
340+
freqLow = 65000;
341+
freqHigh = 76000;
342+
break;
343+
default:
344+
freqLow = 65000;
345+
freqHigh = 108000;
346+
break;
347+
}
348+
if (newFreq < freqLow) newFreq = freqLow;
349+
if (newFreq > freqHigh) newFreq = freqHigh;
350+
uint16_t regChannel = RDA5807.regList[RADIO_REG_CHAN] &
351+
(RADIO_REG_CHAN_SPACE | RADIO_REG_CHAN_BAND);
352+
uint16_t newChannel = (newFreq - freqLow) / RDA5807.channelSpacing;
353+
regChannel += RADIO_REG_CHAN_TUNE; // enable tuning
354+
regChannel |= newChannel << 6;
355+
RDA5807.regList[RADIO_REG_CTRL] |=
356+
RADIO_REG_CTRL_OUTPUT | RADIO_REG_CTRL_UNMUTE |
357+
RADIO_REG_CTRL_RDS | RADIO_REG_CTRL_ENABLE; // | RADIO_REG_CTRL_NEW
358+
RDA5807.regList[RADIO_REG_CHAN] = regChannel;
359+
RDA_WriteAllInfo();
360+
}
361+
362+
void RDA_SetBand(enum RADIO_BAND newBand) {
363+
RDA5807.band = newBand;
364+
switch (newBand) {
365+
case RADIO_BAND_US:
366+
RDA5807.regList[RADIO_REG_CHAN] &= !RADIO_REG_CHAN_BAND;
367+
RDA5807.regList[RADIO_REG_CHAN] |= RADIO_REG_CHAN_BAND_US;
368+
break;
369+
case RADIO_BAND_JP:
370+
RDA5807.regList[RADIO_REG_CHAN] &= !RADIO_REG_CHAN_BAND;
371+
RDA5807.regList[RADIO_REG_CHAN] |= RADIO_REG_CHAN_BAND_JP;
372+
break;
373+
case RADIO_BAND_WW:
374+
RDA5807.regList[RADIO_REG_CHAN] &= !RADIO_REG_CHAN_BAND;
375+
RDA5807.regList[RADIO_REG_CHAN] |= RADIO_REG_CHAN_BAND_WW;
376+
break;
377+
case RADIO_BAND_EE:
378+
RDA5807.regList[RADIO_REG_CHAN] &= !RADIO_REG_CHAN_BAND;
379+
RDA5807.regList[RADIO_REG_CHAN] |= RADIO_REG_CHAN_BAND_EE;
380+
break;
381+
default:
382+
break;
383+
}
384+
RDA5807.regList[RADIO_REG_CHAN] |= RADIO_REG_CHAN_SPACE_100;
385+
RDA_WriteAllInfo();
386+
}
387+
```
388+
201389
### GUI部分
202390

203391
GUI部分我新建了一个线程,根据各个标志位来判断模式,显示各类信息
@@ -447,5 +635,9 @@ static void gpio_isr_handler(void *arg) {
447635
}
448636
```
449637
638+
## 感悟与心得
639+
640+
初次上手乐鑫,我感觉乐鑫的例程还是十分丰富的。由于在使用STM32时,我已经对cmake有一个初步的掌握了,转到乐鑫的esp-idf时就显得不那么费力了,也能继续用我熟悉的CLion了。但是似乎对于那些只熟悉MDK-ARM或者IAR的嵌入式开发者,转而使用乐鑫idf就似乎显得要学的东西有点多了。
450641
642+
再对比下当下STM32和ESP32的价格和性能,ESP32还真是便宜大碗啊,还有着WiFi功能。尽管ESP的库比ST的Hal库庞大亿点,深入调试略微麻烦,有些库甚至封装成了lib,但还是在群友的帮助下解决了问题。
451643

firmware/firmware.bin

977 KB
Binary file not shown.

firmware/firmware.elf

11.1 MB
Binary file not shown.

img/流程图.png

28.8 KB
Loading

0 commit comments

Comments
 (0)